![]() ![]() ![]() ![]() ![]() ![]() |
In this step, you will add additional mappings to the existing query. In the previous sections, you mapped some data from the source type defined by the PriceQuote.xsd
XML Schema to the target type defined by the Quote.xsd
XML Schema. In this section, you will map additional data from the source types (defined by the PriceQuote.xsd
XML Schema, the AvailQuote.xsd
XML Schema, and the Java float primitive: taxRate
) to the target type (defined by the Quote.xsd
XML Schema) as shown in the following figure.
Mappings created in this section will create a join between repeating elements in the source and target XML Schemas. Complete the following tasks to create, test, and alter the join:
In this task, you will create a user-defined Java method in the MyTutorialJoin Transformation file that calculates the total price of the widgets requested including tax. In Call the calculateTotalPrice User Method From the Query, you will change the query to invoke this method.
MyTutorialJoin.java
. A User method is created in the MyTutorialJoin Transformation file.
newusermethod1
will be added in the Source. Rename this method to calculateTotalPrice
.calculateTotalPrice
Java method:@com.bea.wli.transform.XQueryFunction()
public java.lang.String calculateTotalPrice() {
return "";
}
With the following calculateTotalPrice
Java method:
public float calculateTotalPrice(float taxRate, int quantity, float price, boolean fillOrder)
{
float totalTax, costNoTax, totalCost;
if (fillOrder)
{
// Calculate the total tax
totalTax = taxRate * quantity * price;
// Calculate the total cost without tax
costNoTax = quantity * price;
// Add the tax and the cost to get the total cost
totalCost = totalTax + costNoTax;
}
else
{
totalCost = 0;
}
return totalCost;
}
Note: | Ensure you modify the return type of the calculateTotalPrice function from String to float . |
myJoin.xq
in the Design view:These nodes are both repeating nodes. A repeating node means more than one instance of this node can be specified. The + symbol to the right of the node indicates these nodes are repeating nodes.
WARNING: | You must select the priceRequest node and not the priceRequests node. |
A dashed line linking the two repeating nodes is displayed, as shown in the following figure.
The dashed line with short dashes represents a structural link—a link between two parent structures that does not map data directly.
To learn more about XML repeating nodes, see Understanding XML Repeating Nodes.
A dashed line linking the two repeating elements is displayed, as shown in the following figure.
The following query is displayed in Source:
declare namespace xf = "http://tempuri.org/Tutorial_Project_Web/src/requestquote/myJoin/";
declare namespace ns0 = "http://www.example.org/price";
declare namespace ns1 = "http://www.example.org/avail";
declare namespace ns2 = "http://www.example.org/quote";
declare function xf:myJoin($priceQuote1 as element(ns0:priceQuote),
$availQuote1 as element(ns1:availQuote),
$taxRate as xs:float)
as element(ns2:quote) {
<ns2:quote>
<name>{ data($priceQuote1/ns0:customerName) }</name>
<address>{ concat($priceQuote1/ns0:shipAddress/@street ,",", $priceQuote1/ns0:shipAddress/@city ,",", fn:upper-case($priceQuote1/ns0:shipAddress/@state) , ",",$priceQuote1/ns0:shipAddress/@zip) }</address>
{
for $priceRequest in $priceQuote1/ns0:priceRequests/ns0:priceRequest,
$availRequest in $availQuote1/ns1:availRequest
return
<quoteResponse/>
}
</ns2:quote>
};
declare variable $priceQuote1 as element(ns0:priceQuote) external;
declare variable $availQuote1 as element(ns1:availQuote) external;
declare variable $taxRate as xs:float external;
xf:myJoin($priceQuote1,
$availQuote1,
$taxRate)
In the preceding query, there are no data links between the children of the repeating nodes, so the quoteResponse
element is empty. (The string: <quoteResponse/>
is an empty node.)
The structural links between the repeating nodes generates the for
loop which is shown in bold in the preceding query listing. This XQuery for
loop iterates through the set of priceRequest
and availReqest
repeating elements. For example, if the source XML data to this query contains three instances of the priceRequest
element and three instances of the availRequest
element, the for
loop would execute a total of nine times with the following combinations:
priceRequest
element with the first instance of availRequest
element.priceRequest
element with the second instance of availRequest
element.priceRequest
element with the third instance of availRequest
element.priceRequest
element with the first instance of availRequest
element.priceRequest
element with the second instance of availRequest
element.priceRequest
element with the third instance of availRequest
element.priceRequest
element with the first instance of availRequest
element.priceRequest
element with the second instance of availRequest
element.priceRequest
element with the third instance of availRequest
element.For some transformations, you may want the query to generate all the possible combinations but for others, you may want to constrain the combinations as described in the following steps.
A line between the two widgetId nodes is displayed, as shown in the following figure.
The following query is displayed:
declare namespace xf = "http://tempuri.org/Tutorial_Project_Web/src/requestquote/myJoin/";
declare namespace ns0 = "http://www.example.org/price";
declare namespace ns1 = "http://www.example.org/avail";
declare namespace ns2 = "http://www.example.org/quote";
<name>{ data($priceQuoteDoc/ns0:customerName) }</name>
declare function xf:myJoin($priceQuote1 as element(ns0:priceQuote),
$availQuote1 as element(ns1:availQuote),
$taxRate as xs:float)
as element(ns2:quote) {
<ns2:quote>
<name>{ data($priceQuote1/ns0:customerName) }</name>
<address>{ concat($priceQuote1/ns0:shipAddress/@street
,",",$priceQuote1/ns0:shipAddress/@city ,",", fn:upper-case($priceQuote1/ns0:shipAddress/@state) , ",", $priceQuote1/ns0:shipAddress/@zip) }</address>
{
for $priceRequest in $priceQuote1/ns0:priceRequests/ns0:priceRequest,
$availRequest in $availQuote1/ns1:availRequest
where data($priceRequest/ns0:widgetId) = data($availRequest/ns1:widgetId)
return
<quoteResponse/>
}
</ns2:quote>
};
declare variable $priceQuote1 as element(ns0:priceQuote) external;
declare variable $availQuote1 as element(ns1:availQuote) external;
declare variable $taxRate as xs:float external;
xf:myJoin($priceQuote1,
$availQuote1,
$taxRate)
The link between the widgetId nodes generates the where
clause in the for
loop, as shown in bold in the preceding query listing. This where
clause constrains or limits the output of the for
loop. Specifically, the where
clause specifies that if the expression in the where
clause is true, the for
loop will output the contents of the return
. For this example, if the widgetId of the availRequest
element is equal to the widgetId of the priceQuest
element, the following XML data is returned:
<quoteResponse/>
An empty quoteReponse
element isn't very useful. In the following task:
Add Links to Populate the quoteResponse Element, you will add data links that will populate the quoteResponse
element.
Note: | In the next section, to calculate the total cost of the order, you will edit the link between the taxRate Java primitive and the quote/quoteResponse/totalCost node. |
In the Design view, the following links are displayed, as shown in the following figure.
$float-var
parameter of the General Expression pane.In the General Expression pane, the default argument: $float_var is replaced with the $taxRate argument and the next argument becomes selected.
Select $int-var
in the General Expression pane.
In the General Expression pane, the default argument: $int_var is replaced with the $availRequest/ns1:requestedQuantity argument and the next argument becomes selected.
Select $float-var
in the General Expression pane.
In the General Expression pane, the default argument: $float_var is replaced with the $priceRequest/ns0:price argument and the next argument becomes selected.
Select $boolean-var
in the General Expression pane.
In the General Expression pane, the default argument: $boolean_var is replaced with the $availRequest/ns1:quantityAvail argument, as shown in the following figure.
The following query is displayed in Source view:
declare namespace xf = "http://tempuri.org/Tutorial_Project_Web/src/requestquote/myJoin/";
declare namespace ns0 = "http://www.example.org/price";
declare namespace ns1 = "http://www.example.org/avail";
declare namespace ns2 = "http://www.example.org/quote";
declare function xf:myJoin($priceQuote1 as element(ns0:priceQuote),
$availQuote1 as element(ns1:availQuote),
$taxRate as xs:float) as element(ns2:quote)
{
<ns2:quote>
{
<name>{ data($priceQuote1/ns0:customerName) }</name>
<address>{ concat($priceQuote1/ns0:shipAddress/@street ,",", $priceQuote1/ns0:shipAddress/@city ,",", fn:upper-case($priceQuote1/ns0:shipAddress/@state) , ",", $priceQuote1/ns0:shipAddress/@zip) }</address>
{
for $priceRequestin$priceQuote1
/ns0:priceRequests/ns0:priceRequest,
$availRequest in $availQuote1/ns1:availRequest
wheredata($priceRequest/ns0:widgetId)
=data($availRequest/ns1:widgetId)
return
<quoteResponse>
<widgetId>{ data($priceRequest/ns0:widgetId) }</widgetId>
<unitPrice>{ data($priceRequest/ns0:price) }</unitPrice>
<requestedQuantity>
{data($availRequest/ns1:requestedQuantity) }</requestedQuantity>
<fillOrder>{ data($availRequest/ns1:quantityAvail) }</fillOrder>
</quoteResponse>
{
for $shipDate in $availRequest/ns1:shipDate
return
<shipDate>{ data($shipDate) }</shipDate>
}
<taxRate>{ $taxRate }</taxRate>
<totalCost>{ calculateTotalPrice($taxRate,
$availRequest/ns1:requestedQuantity,
$priceRequest/ns0:price,
$availRequest/ns1:quantityAvail) }</totalCost>
}
</ns2:quote>
The links added in the preceding task generate the additional XQuery source code listed between the <quoteResponse>
and </quoteResponse>
tags highlighted in bold in the preceding query listing.
In this task, you create an instance of the MyTutorialJoin.java
control.
Note: | Switch from XQuery Transformation perspective to Process perspective to create a control. Click Window![]() ![]() ![]() |
Tutorial_Project_Web\src\requestquote\RequestQuote.java
and select the Design tab.An instance called MyTutorialJoin.java is created in your project and displayed in the Controls pane as shown by the following figure:
In this task, you edit the Combine Price and Avail Quotes node in the RequestQuote business process and change the instance that gets invoked by this node from an instance of the TutorialJoin.java
to an instance of the MyTutorialJoin.java.
Additionally, you change the design of the Combine Price and Avail Quotes node to call the myJoin()
method on the MyTutorialJoin control. The myJoin()
method combines the data returned to your business process from different systems creating a single XML response document (quote) that is subsequently returned to the business process's client.
The node builder opens on the General Settings pane.
QuoteDocument
myJoin()
from the Method field.
The Select variables to assign fields are populated with default variables. The data types match the data type expected in the source parameters to the myJoin
() method as shown in the following list:
priceQuote holds the price quote data, which is returned from the PriceProcessor service in the For Each loop in your business process.
availQuote holds the availability quote data, which is returned from the AvailProcessor service in the For Each loop in your business process.
taxRate holds the rate of sales tax applied to the quote, based on the shipping address, which is returned to your business process from the taxCalculation service.
The Control Expects fields are populated with the data type expected by the myJoin()
method on the MyTutorialJoin control, as shown in the following figure.
On the Receive Data tab, the Select variables to assign field is populated with the default variable: Quote. The data type matches the data type expected in the target parameter to the myJoin
() method. The Control Expects field is populated with the data type returned by the myJoin
() method: QuoteDocument, as shown in the following figure.
Earlier in this tutorial, you entered the XML data that is run against the query. During run time, the business process builds the XML data and passes it to the query that was built in this tutorial. To run the business process and invoke the query, follow the instructions in Step 12: Run the RequestQuote Business Process in the Tutorial: Building Your First Business Process.
![]() ![]() ![]() |