Request/Response Example

Imagine we need to process a message requesting information about a specific policy product (message tc=201, as defined by ACORD standards). The ACORD message looks like this:

<tx:TXLife xmlns:tx="http://ACORD.org/Standards/Life/2">
	<tx:UserAuthRequest>
		<tx:UserLoginName>username</tx:UserLoginName>
		<tx:UserPswd>
			<tx:Pswd>password</tx:Pswd>
		</tx:UserPswd>
	</tx:UserAuthRequest>
 
	<tx:TXLifeRequest>
		<tx:TransRefGUID>2fac30d5-cd66-4eaa-833f-9f4989db796b</tx:TransRefGUID>
		<tx:TransType tc="201">Policy Product Inquiry</tx:TransType>
		<tx:TransExeDate>2007-06-01</tx:TransExeDate>
		<tx:TransExeTime>17:00:13-05:00</tx:TransExeTime>
		<tx:InquiryLevel tc="1">OLI_INQUIRY_OBJ</tx:InquiryLevel>
 
		<tx:OLifE Version="2.14.00">
			<tx:PolicyProduct id="PolicyProduct_1">
				<tx:CarrierCode>1002</tx:CarrierCode>
				<tx:ProductCode>VWL01</tx:ProductCode>
			</tx:PolicyProduct>
		</tx:OLifE>
	</tx:TXLifeRequest>
</tx:TXLife>

You can see how the message is a Policy Product Inquiry concerning the PolicyProduct provided by carrier "1002" using the product code "VWL01."

The XQuery code is as simple as this:

declare namespace tx = "http://ACORD.org/Standards/Life/2";
import module namespace example = "http://www.datadirect.com/xquery/examples" at "acord_verbs.xquery";
 
<tx:TXLife> {
	for $request in doc("201-1.xml")/tx:TXLife/tx:TXLifeRequest
	return example:reply-201($request)
}
</tx:TXLife>

The exampe:reply-201 function analyzes the TXLifeRequest content and fetches the relevant information from the relational repository:

declare function example:reply-201($request as element(tx:TXLifeRequest)) as element(tx:TXLifeResponse)? {
	let $results :=
		for $policyProduct at $pos in $request/tx:OLifE/tx:PolicyProduct
		let $carrierCode := xs:string($policyProduct/tx:CarrierCode)
		let $productCode := xs:string($policyProduct/tx:ProductCode)
		for $policy in collection("ACORD_POLICY")/ACORD_POLICY
					[CarrierCode eq $carrierCode]
					[ProductCode eq $productCode]
		return <tx:PolicyProduct> {
		attribute id {fn:concat("PolicyProduct_", xs:string($pos))},
			$carrierCode,
			<tx:PlanName>{xs:string($policy/PlanName)}</tx:PlanName>,
			$productCode,
			<tx:MarketingName>{xs:string($policy/MarketingName)}</tx:MarketingName>
			}</tx:PolicyProduct>
		return 
		example:create-response(
			$request,
			(<tx:TransResult>
				<tx:ResultCode tc="1">Success</tx:ResultCode>
			</tx:TransResult>,
			<tx:OLifE Version="2.12.00">
				{$results}
			</tx:OLifE>
			)
	)
};

Note how the relational repository is accessed by the XQuery function:

for $policy in collection("ACORD_POLICY")/ACORD_POLICY[CarrierCode eq $carrierCode][ProductCode eq $productCode]

The first "for" instruction iterates over each PolicyProduct element from the request (there could be more than one); then, for each PolicyProduct the carrier and product code are used as keys to retrieve the information from the database.

The response is formatted according to the required ACORD structure:

(: Creates a TXLife message with non-empty TXLifeResponse :)
declare function example:create-response(
		$request as element(tx:TXLifeRequest),
		$payLoad as element()*) as element(tx:TXLifeResponse) {
 
	<tx:TXLifeResponse> {
		$request/tx:TransRefGUID,
		$request/tx:TransType,
		<tx:TransExeDate>{example:formatDate(fn:current-date())}</tx:TransExeDate>,
		<tx:TransExeTime>{example:formatTime(fn:current-time())}</tx:TransExeTime>,
		$payLoad
	}
	</tx:TXLifeResponse>
};

From the XQuery author’s point of view, the relational model is navigated as if it was an XML structure; under the covers, DataDirect XQuery™ will issue the proper SQL statements to fetch the entries in the ACORD_POLICY table that match carrier and product codes.

A similar example is a “party search” (tc=301); in this case the message we receive is this one (click here for the XML document):

<tx:TXLife xmlns:tx="http://ACORD.org/Standards/Life/2">
	<tx:UserAuthRequest>
		<tx:UserLoginName>username</tx:UserLoginName>
		<tx:UserPswd>
			<tx:Pswd>password</tx:Pswd>
		</tx:UserPswd>
	</tx:UserAuthRequest>
 
	<tx:TXLifeRequest>
		<tx:TransRefGUID>e6c00b0e-94d4-4e48-8857-1690945df1c4</tx:TransRefGUID>
		<tx:TransType tc="301">Party Search</tx:TransType>
		<tx:TransExeDate>2007-06-01</tx:TransExeDate>
		<tx:TransExeTime>17:00:13-05:00</tx:TransExeTime>
		<tx:CriteriaExpression>
			<tx:CriteriaOperator tc="2">AND</tx:CriteriaOperator>
			<tx:Criteria>
			<tx:ObjectType tc="115">Person</tx:ObjectType>
			<tx:PropertyName>LastName</tx:PropertyName>
			<tx:PropertyValue tc="+1">Roberts</tx:PropertyValue>
			<tx:Operation tc="1">Equal</tx:Operation>
			</tx:Criteria>
			<tx:Criteria>
				<tx:ObjectType tc="115">Person</tx:ObjectType>
				<tx:PropertyName>FirstName</tx:PropertyName>
				<tx:PropertyValue>Edward</tx:PropertyValue>
				<tx:Operation tc="1">Equal</tx:Operation>
			</tx:Criteria>
		</tx:CriteriaExpression>
 
		<tx:OLifE Version="2.14.00">
		</tx:OLifE>
	</tx:TXLifeRequest>
</tx:TXLife>

The search criteria could be more complicated than what illustrated here (see 301-5.xml for example). The XQuery processing this message can be something like this (click here for the XQuery document):

import module namespace example = "http://www.datadirect.com/xquery/examples" at "acord_verbs.xquery";
 
declare namespace tx="http://ACORD.org/Standards/Life/2";
 
declare variable $request as document-node(element(*, xs:untyped)) external;
 
<tx:TXLife> {
	for $r in $request/tx:TXLife/tx:TXLifeRequest
	return example:reply-301($r)
	}
</tx:TXLife>

You can browse acord_verbs.xquery to find details about how the request is processed. Note that in this case, to simulate a more realistic scenario, we are not processing the request message as a file (accessed through the fn:doc() function), but the request is bound externally to the $request variable. This means that the Java code invoking the XQuery is responsible for binding the proper ACORD request message to the variable before executing the XQuery; see Using DataDirect XQuery™ to Bind External Variables to Dynamic Values for details about how that can be done.

What's Next

Go to Performing a Search and Inquiry Using Multiple Joins to see how you can perform complex searches and queries using multiple joins.

Prev: "XQuery ACORD Examples"

Next: "Search and Inquiry Using Multiple Joins"


Copyright © 1993 - 2008. Progress Software Corporation. All rights reserved. | N. America: 800 876 3101 | World: +44 (0) 1753 218 930