|
Home:Learn XQuery:White Papers:ACORD:Request/Response Example
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.
|