Suppose now our system receives a message containing an address change request (tc=181 in ACORD parlance). Before even processing it, however, we want to make sure the message is semantically valid (not just valid in terms of the ACORD standards); in particular we want to ensure that:
The XQuery implementing such validation is shown here (click this link to open the XQuery document):
declare namespace tx="http://ACORD.org/Standards/Life/2";
import module namespace example = "http://www.datadirect.com/xquery/examples" at "acord_verbs.xquery";
(: Example of business validation on an "Address Change" request :)
let $request := doc("181-1.xml")
return example:validate-181($request/tx:TXLife/tx:TXLifeRequest)
As you can see in acord_verbs.xquery, example:validate-181() fetches data from two relational tables (ACORD_PERSON and ACORD_ADDRESS), performs the various checks, and returns either an empty result (no errors; success), or a message describing the error condition (failure). The first part of the function is particularly interesting, as it is responsible for implementing the actual business validation rules:
declare function example:validate-181($request as element(tx:TXLifeRequest)) as element(tx:TXLifeResponse)? {
let $party := $request/tx:OLifE/tx:Party[@id eq $request/@PrimaryObjectID]
let $key := xs:string($party/tx:PartyKey)
let $person := collection("ACORD_PERSON")/ACORD_PERSON[PartyKey eq $key]
let $oldAddress := $party/tx:Address[@DataRep eq "Removed"]
let $newAddress := $party/tx:Address[@DataRep eq "Full"]
let $row := collection("ACORD_ADDRESS")/ACORD_ADDRESS
[OwnerKey eq $key]
[AddressTypeCode eq xs:integer($oldAddress/tx:AddressTypeCode/@tc)]
[Line1 eq $oldAddress/tx:Line1]
[City eq $oldAddress/tx:City]
(: AddressState is nullable :)
[AddressState eq $oldAddress/tx:AddressState
or
fn:empty(AddressState) and fn:empty($oldAddress/tx:AddressState)]
[Zip eq $oldAddress/tx:Zip]
[AddressCountry eq $oldAddress/tx:AddressCountry]
let $rowValid := fn:count($row) eq 1
let $zipState :=
if ( $newAddress/tx:AddressCountry eq "USA" )
then
example:getZipInfo($newAddress/tx:Zip)
else
()
...
Validation of the ZIP code, when "AddressCountry" is "USA" is delegated to the example:getZipInfo() function, which in turns delegates validation to a third party public Web Service, published by http://www.webservicemart.com (http://www.webservicemart.com/uszip.asmx):
declare function example:getZipInfo($zipCode as xs:string) as element()? {
let $response :=
ddtek:wscall(
<ddtek:location address="http://www.webservicemart.com/uszip.asmx"
soapaction="http://webservicemart.com/ws/ValidateZip"/>,
<ws:ValidateZip>
<ws:ZipCode>{$zipCode}</ws:ZipCode>
</ws:ValidateZip>
)/ws:ValidateZipResponse/ws:ValidateZipResult
return
(: because the webservice returns the result as text (not xml) wrapped
in a ValidateZipResult node we have to parse the content :)
ddtek:parse($response/text())/*
};
Thanks to the ddtek:wscall() function, invoking external Web Service from a DataDirect XQuery™ is extremely simple, as you can see.
![]()
Now that you see how to use DataDirect XQuery™ to validate data, go to Updating a Relational Database to learn how to update relational data with DataDirect XQuery™.
![]()