This section provides example scenarios for the Sample Project located in your BEA XQuery Mapper installation. To learn more about opening the Sample Project, see XQuery Mapper Sample Project.
This section includes the following topics:
You can use the XQuery Mapper to combine the contents of two different schemas, as shown in the following Figure 3-1.
In this example, customer data (as described in the CustInfo.xsd
schema) is merged with a repeating element (line-items
, as described in the PO.xsd
schema) to form a single XML document valid against the POCustInfo.xsd
schema.
For this example, the parent folder should be Samples/XQueryTransformations
combineData.
CustInfo.xsd\customer
PO.xsd\purchase-order
POCustInfo.xsd\purchase-order
After selecting the source and target data, the combineData.xq
file is created.
|
||
|
||
|
||
|
||
|
||
|
||
|
As shown in the following figure, a dotted line represents a Structural link. This type of link is created between two parent structures that do not map data directly.
As shown in the following figure, a solid line represents a Data link. This type of link converts the value of the source node directly to the value of the target node.
To learn more about links, see Understanding Design View Graphical Representations.
The map between the Source and Target elements is shown in the following figure.
For information about testing XQuery Transformations, see Testing XQuery Files.
In this section, PriceQuote.xsd
, AvailableQuote.xsd
, and taxrate.xsd
are joined to create a single Quote.xsd
file.
This example includes the following steps:
In this section you will create an XQuery transformation using the AvailQuote.xsd, PriceQuote.xsd
, and taxrate.xsd
files. After doing so, you will map several priceQuote
and availRequest
source elements to corresponding target elements.
Join
. PriceQuote.xsd\priceQuote
PriceQuote.xsd\taxRate
AvailQuote.xsd\availRequest
Quote.xsd\quote
After selecting the source and target data, the Join.xq
file is created in the Samples/XQueryTransformations folder.
|
||
|
||
|
||
|
The source documents priceQuote
and availRequest
share the common element, widgetId
. In this sub-section, you add a conditional constraint that specifies that if the widgetId
of the availRequest
element is equal to the widgetId
of the priceRequest
element, then the merged repeating element quoteResponse
should be returned.
join.xq
in the Design view.priceRequests/priceRequest/widgetId
availRequest/widgetId
A line between the two widgetId nodes (to indicate that you merged the elements) is displayed, as shown in the following figure.
The link between the widgetId nodes generates:
</quoteResponse>
The quoteResponse element is empty. Use the procedure in Step 3. Add Links to Populate Empty Element to add data links that will populate the quoteResponse
Use the procedure in this section to add data links to populate the quoteResponse element.
In this step, you will add the function for calculating the total cost of the purchase order to the XQuery source.
Join.xq
file in Source view. declare function xf:calculateTotalPrice($taxRate as xs:float, $quantity as xs:float,$price as xs:float)
as xs:float {
let $taxQuantity := ($taxRate * $quantity)
let $totalTax := ($taxQuantity * $price)
let $costNoTax := ($quantity * $price)
let $totalCost := ($totalTax + $costNoTax)
return $totalCost
};
Join.xq
file in Design view. Note: | Your Join.xq file now includes two function declarations: calculateTotalPrice and Join. Note that when you have more than one function in an XQ file, the function with the same name as the XQ file is rendered in the Design View. (In this case, the Join function is displayed in the Design view.) |
xf:calculateTotalPrice($taxRate,$availRequest/ns1:requestedQuanity,$priceRequest/ns0:price)
The expression is added to the totalCost element in your XQuery.
Creating a constraint using the Where Clause Expression pane of the Constraints tab adds a where
clause to the XQuery for
loops—limits the target repeating elements that are returned during run time.
During run time, the for
loop will iterate only over those repeating elements that meet the complex condition. In this section, you will add another condition (resulting in a complex condition) to the where
of the for
loop to further limit what is returned by the for
loop.
join.xq
file.
The single condition that makes up the where
clause is displayed in Where Clause Expression pane of the Constraints tab.
data($priceRequest/ns0:widgetId) = data($availRequest/ns1:widgetId)
data($availRequest/ns1:requestedQuanity)
Note: | You must use the quotes around 50. That is, enter "50", not 50. |
The Join Type determines how the conditions that make up where
clause are evaluated during run time.
where
clause of the for
loop. where
clause:where (data($availRequest/ns1:widgetId) = data($priceRequest/ns0:widgetId)
and data($availRequest/ns1:requestedQuanity) < "50")
For information about testing XQuery transformations, see Testing XQuery Files.
Specifically for this example, complete the following steps to set up the test to verify that the XQuery works when both the constraints you configured in Step 5. Add a Constraint With Multiple Conditions are met:
<ns0:widgetId>value
</ns0:widgetId>
<ns0:widgetId>value
</ns0:widgetId>
<ns0:requestedQuanity>25</ns0:requestedQuanity>
In this example, you will use the Union option in the Constraints tab to construct an XQuery that maps data of the same type into larger sets of data.
In this example the parent folder is Samples/XQueryTransformations.
union
. PO.xsd\purchase-order
twice): PO.xsd\purchase-order
PO.xsd\purchase-order
Note: | To add the same element twice, you need to change the parameter name. |
Order.xsd\order
After selecting the source and target data, the union.xq
file is created.
|
||
|
The following graphic displays the Design tab of the linking.
$purchase-order/line-items/line-item
(repeating element in the Source pane) and the order/items/item
(repeating element in the Target pane) is selected before you proceed.part-no
element in the Source pane and the part-number
element in the Target pane. Note: | In the Source and Target pane, if the element names are the same, you can use the Induce Map right-click menu option instead of manually creating the link as described in this step. For more information, see Link Menu Options. |
Because the two structural links have the union constraint applied to them, a set of implied data links between the second set of sub-elements is generated as shown in Figure 3-9. The solid gray lines represents implied links that were created by selecting union in the Constraints Tab.
For more information about testing XQuery transformations see Testing XQuery Files.
This example shows how to map a repeating element a non-repeating single element. In this example, you will create a transformation that takes the value of a repeating XML element (defined by a source schema) and maps it to a single element in a target XML document (defined in a target schema) as shown in the following figure.
In this example the parent folder is Samples/XQueryTransformations
repeatToNonRepeat
. Dates.xsd\dates
PODate.xsd\PODate
dates/date
) and drag it the first single element (PODate/billing-date
) in the Target pane.Keep this link selected for the next step.
dates/date/type
node and drop it into the Left Hand Expression pane of the Where Clause Expression in the Constraints tab. "BILLING"
.Use quotes when entering a date string, as shown in the following figure.
The constraint created in the preceding steps specifies that the value of the dates/date/type
element in an XML document is compared to the value "BILLING".
In the next steps, you will add XQuery code to the for loop to return specified data when the value of the dates/date/type
element equals "BILLING".
dates/date/value
element and drag to the PODate/billing-date
element in the Target pane.
During run time, this data link will return the value of datesDoc/date/value
as the value of billing-date
if the constraint: data($date/ns1:type) = "BILLING"
evaluates to true.
dates/date
) and drag it the second single element (PODate/delivery-date
) in the Target pane.A dashed line linking the two elements is displayed.
Keep this link selected for the next step.
dates/date/type
node and drop it into the Left Hand Expression pane of the Where Clause Expression in the Constraints tab. "DELIVERY"
. The next step will add the XQuery code to return data if during run time the constraint is equal to true.Note: | Use quotes when entering string values. |
During run time, the constraint created in step, tests if datesDoc/date/type
is equal to the string: "DELIVERY"
.
datesDoc/date/value
element and drag it the PODate/delivery-date
element in the Target pane.
During run time, this data link will return the value of dates/date/value
as the delivery-date
if the constraint: data($date/ns1:type) = "DELIVERY"
evaluates to true.
For more information about testing XQuery files, see Testing XQuery Files.
This example shows how to map a a non-repeating element to a a repeating element. In this example, you will create a transformation that during run time will take a single source element and maps it to repeating target element as shown in the following figure.
In this example the parent folder is Samples/XQueryTransformations.
nonRepeatToRepeat
. PODate.xsd\PODate
Dates.xsd\dates
After selecting the source and target data, the nonRepeatToRepeat.xq
file is created.
The following XQuery code is generated:
<ns1:dates>
{
for $PODate in $PODate1/ns0:billing-date union $PODate1/ns0:delivery-date
return
<ns1:date/>
}
</ns1:dates>
During run time, the for
loop in the preceding XQuery code is executed twice. The first time the for
loop is run, the iteration variable $PODate
is equal to the first element in the union: $PODate1/ns0:billing-date
and the second time the for
loop is run the iteration variable $PODate
is equal to the second element in the union: $PODate1/ns0:delivery-date
.
The XML data returned by the preceding query returns two empty elements: <ns1:date/>
.
The following steps will add the XQuery code to return the billing and delivery dates to the query.
pODate/billing-date
element and drag it the dates/value
element in the Target pane.Two data links are created as shown in the following figure.
The structural links (pODate/billing-date
to dates/date
) and (pODate/delivery-date
dates/date
) are joined when you created the link from the pODate/billing-date
element to the dates/value
element (dates/value
), a second data link between the pODate/delivery-date
element and dates/value
element is automatically created.
pODate/billing-date
element and drag it the dates/type
element in the Target pane.
Keep the pODate/billing-date
to dates/type
link selected for the next step.
The XQuery if-then-else construct is added to the link. For example, the following XQuery source code segment for the link is replaced:
data($PODate)
By the following XQuery source code segment for the link:
if (fn:boolean("true")) then
data($PODate)
else
()
The If Condition pane is displayed.
$node-var
argument selected.pODate
Structural Link variable over the $node-var
argument of the local-name
function in the If Condition pane. BILLING DATE
" then click Add.Note: | Use quotes when entering string values. |
As shown in the following figure, the condition is added to the if section of the if-then-else.
BILLING
"data($PODate)
Note: | You must use quotes around the "BILLING " string. |
DELIVERY
"Note: | You must enter quotes around the "DELIVERY " string. |
The XQuery code is displayed in the Expression Structure pane, as shown in the following figure.
For more information about testing XQuery files, see Testing XQuery Files.
In this example, you will be creating an XQuery transformation that calculates price based on a widget ID and state tax rate. Using the XQuery Mapper, you will create an expression structure that represents the following if-then-else logic:
This example includes the following steps:
In this step, you will create a new XQuery transformation using the PurchaseAgree.xsd
and Supplier.xsd
.
In this example the parent folder is Samples/XQueryTransformations.
ifthenelse
. Supplier.xsd\Supplier
PurchaseAgree.xsd\PurchaseOrder
After selecting the source and target data, the ifThenElse.xq
file is created.
In this step, you will be creating an If expression that states: If the widget ID is between 0-200, then the price is $10.00.
In the Expression Structure pane, verify that the If Condition is highlighted.
"0"
.Note: | Use quotes when entering a numeric value. |
"200"
.Note: | Use quotes when entering a numeric value. |
Note: | Delete existing data in the Edit Then Expression pane. Use quotes when entering "$10.00". |
Validate that your if then statement appears as shown in the following:
In this step, you will be creating a nested If expression that states: If the widget ID is between 201-400, then the price is $20.00. To accomplish this, you will insert a nested If-Then-Else inside the Else Expression created in Step 2. Create First If Condition.
"201"
.Note: | Use quotes when entering a numeric value. |
"400"
.Note: | Use quotes when entering a numeric value. |
Note: | Use quotes when entering a numeric value. |
Validate that your statement appears as shown in the following:
In this step, you will be creating an If expression that states: If the widget ID is between 401-600, then the price is $30.00. To accomplish this, you will insert a nested If-Then-Else inside the Then Expression created in Step 3. Create First Nested If-Then-Else Condition.
Note: | Be sure to select the Else Expression created in Step 3. Create First Nested If-Then-Else Condition |
"401"
.Note: | Use quotes when entering a numeric value. |
"600"
.Note: | Use quotes when entering a numeric value. |
Note: | Use quotes when entering a numeric value. |
Validate that your statement appears as shown in the following figure.
For more information about testing XQuery files, see Testing XQuery Files.
This example shows how to create a map with schemas that have recursive elements. A recursive element contains a child element of the same type as the parent as shown in the following figure. In this example, the product
element is a recursive element because it is of type: productType
and productType
contains a child-product
element which is also of type productType
(productType
refers to itself).
In this example the parent folder is, Samples/XQueryTransformations.
recursive
. SupplierAcme.xsd\supplier-acme
Product.xsd\product
After selecting the source and target data, the recursive.xq
file is created.
As shown in the following figure, the product
element contains the recursive child-product
element.
For more information about testing XQuery files, see Testing XQuery Files.
You can use the Group by Key Fields functionality to group data based on one or more key values. However, the Group By functionality is not supported graphically in the XQuery Mapper and there is no representation of the XQuery in the Mapper's Design View. Therefore you must write the Group By XQuery construct in the XQuery Mapper's Source View.
In this example, the input-warehouse-id
and the input-location-desc
elements are used as the key fields to group the data in the output document:
input-warehouse-id
element and the input-location-desc
elements. (The values are Warehouse1
and Location1
respectively.)Warehouse1
and Location1
keys in the target (output) document (see Listing 3-3).<input-warehouse-inventory xmlns="http://www.creditpo.org/repkeyin">
<input-line-item>
<input-warehouse-id>Warehouse1</input-warehouse-id>
<input-location-desc>Location1</input-location-desc>
<input-part-no>1</input-part-no>
<input-quantity>10</input-quantity>
</input-line-item>
<input-line-item>
<input-warehouse-id>Warehouse2</input-warehouse-id>
<input-location-desc>Location2</input-location-desc>
<input-part-no>2</input-part-no>
<input-quantity>20</input-quantity>
</input-line-item>
<input-line-item>
<input-warehouse-id>Warehouse1</input-warehouse-id>
<input-location-desc>Location1</input-location-desc>
<input-part-no>3</input-part-no>
<input-quantity>30</input-quantity>
</input-line-item>
</input-warehouse-inventory>
<ns0:output-inventory xmlns:ns0="http://www.creditpo.org/repkeyout";>
<ns0:output-warehouse-inventory>
<ns0:output-warehouse-id>Warehouse1</ns0:output-warehouse-id>
<ns0:output-location-desc>Location1</ns0:output-location-desc>
<ns0:output-line-item>
<ns0:output-part-no>1</ns0:output-part-no>
<ns0:output-quantity>10</ns0:output-quantity>
</ns0:output-line-item>
<ns0:output-line-item>
<ns0:output-part-no>3</ns0:output-part-no>
<ns0:output-quantity>30</ns0:output-quantity>
</ns0:output-line-item>
</ns0:output-warehouse-inventory>
<ns0:output-warehouse-inventory>
<ns0:output-warehouse-id>Warehouse2</ns0:output-warehouse-id>
<ns0:output-location-desc>Location2</ns0:output-location-desc>
<ns0:output-line-item>
<ns0:output-part-no>2</ns0:output-part-no>
<ns0:output-quantity>20</ns0:output-quantity>
</ns0:output-line-item>
</ns0:output-warehouse-inventory>
</ns0:output-inventory>
groupby
. regroupKeyFldIn.xsd\input-warehouse-inventory
regroupKeyFldOut.xsd\output-inventory
After selecting the source and target data, the groupby.xq
file is created.
Note: | At this point, if you were working in the XQuery Mapper in the BEA WebLogic Integration 8.1 release, you could highlight the link between input-warehouse-id and output-warehouse-inventory and choose the Constraint Type Group by Key Fields graphically. However, the Design View representation for this is not available in this release. However, the Group by type is supported—you must manually write the XQuery for it as described in the following steps. |
declare namespace ns0 = "http://www.creditpo.org/repkeyin";
declare namespace ns1 = "http://www.creditpo.org/repkeyout";
declare function Regrouping($input-warehouse-inventory as element(ns0:input-warehouse-inventory))
as element(ns1:output-inventory) {
<ns1:output-inventory>
{
for $input-line-item in $input-warehouse-inventory/ns0:input-line-item
group $input-line-item as $group by
$input-line-item/ns0:input-warehouse-id as $key0,
$input-line-item/ns0:input-location-desc as $key1
return
<ns1:output-warehouse-inventory>
<ns1:output-warehouse-id>{ data($key0) }</ns1:output-warehouse-id>
<ns1:output-location-desc>{ data($key1) }</ns1:output-location-desc>
{
for $group0 in $group return
<ns1:output-line-item>
<ns1:output-part-no>{ xs:byte( data($group0/ns0:input-part-no) ) }</ns1:output-part-no>
<ns1:output-quantity>{ xs:byte( data($group0/ns0:input-quantity) ) }</ns1:output-quantity>
</ns1:output-line-item>
}
</ns1:output-warehouse-inventory>
}
</ns1:output-inventory>
};
declare variable $input-warehouse-inventory as element(ns0:input-warehouse-inventory) external;
Regrouping($input-warehouse-inventory)
The changes are not visible in the Design view. Use the following procedure to Test the XQuery.
In the Result Data pane, click Test XQuery. The resulting data is displayed in the Result Data tab. It displays the line items grouped by key fields similar to that shown in Listing 3-3 (input-warehouse-id is the first key and input-location-desc is the second).
After creating an XQuery transformation in the Design tab, you can test it using the Test tab. When testing XQuery transformations, you can see if the expected XML or Non-XML output is properly generated. You can use the auto-generated XML files or you can use your own custom XML and Non-XML testing files. For more information about XQuery testing, see Testing Map Transformations.
This sections contains the following topics:
The XQuery Mapper automatically generates XML files for testing purposes. Non-XML test files are not automatically generated. For more information, see Using Custom MFL (Non-XML) Files for Testing.
A test XML file becomes available in the Source Variable drop-down menu. The test XML file is based on the source schema This file is not automatically saved, and therefore must be save manually using the Export icon.
Note: | You can also manually edit the test XML by clicking the Source tab. |
The XQuery runs with the source data to generate the results. The results are displayed in the Result Data pane. If an error has occurred, you will see an error message that indicates the problem.
If the auto-generated XML files do not meet your business requirements, you can import custom XML files.
The Import XML File dialog box opens. Use this to locate the XML files used for testing purposes. After selecting the appropriate file it becomes visible in the Source Data pane.
You can also cut and paste test data into the Source Data pane.
The Source XML is tested against the XQuery and the results are displayed.
The XQuery Mapper does not automatically generate Non-XML files. Therefore, when testing Non-XML schema, you must import custom Non-XML test data.
The Import XML File dialog box is displayed. Use this to locate Non-XML files used for testing.
Note: | The Files of type drop-down list must be changed to *.* |
The Source MFL is tested against the target MFL and the results are displayed.