All the lessons in this Primer are based on a real-world scenario.
XYZ.COM is making steady progress in extracting the information from the retailer purchase order to present a correctly formatted web message for the manufacture's web service interfaces. In Lesson 2, we learned that XQuery path expressions can navigate the XML data that describes the purchase order; now we learn how to use another aspect of XQuery, FLWOR (pronounced 'flower') expressions, to query the retailer purchase order and begin to construct the web messages we need.
FLWOR expressions are the workhorse of XQuery. They provide the SQL-style ability to query XML data. FLWOR is a simple mnemonic representing each clause in an expression: for, let, where, orderby and return. FLWOR expressions are often regarded as similar to SELECT-FROM-WHERE statements in SQL. Unlike SQL statements, a FLWOR expression binds variables to values in the for and let clauses. It uses the where clause to filter these bindings with one or more conditions and then uses these variable bindings to create new results.
Now, let's start applying XQuery FLWOR expressions to the purchase order from the retailer. The purchase order, which we use for all examples, is shown here:
<?xml version="1.0"?> <invoicecollection> <invoice> <customer>Wile E. Coyote, Death Valley, CA</customer> <annotation>Customer asked that we guarantee return rights if these items should fail in desert conditions. This was approved by Marty Melliore, general manager.</annotation> <entries n="2"> <entry quantity="2" total_price="134.00"> <product maker="ACME" price="80.00" prod_name="atomic hammer"> </product> </entry> <entry quantity="1" total_price="20.00"> <product maker="ACME" price="20.00" prod_name="power springs"> </product> </entry> </entries> </invoice> <invoice> <customer>Camp Mertz</customer> <entries n="2"> <entry quantity="2" total_price="32.00"> <product maker="BSA" price="16.00" prod_name="left-handed smoke shifter"> </product> </entry> <entry quantity="1" total_price="13.00"> <product maker="BSA" price="13.00" prod_name="snipe call"> </product> </entry> </entries> </invoice> </invoicecollection> |
In this example, we are looking for all products made by the manufacture "ACME" and the amount ordered of each product.
First obtain all the nodes that describe the quantity of each product ordered.
doc("po.xml")//entry/@quantity
|
Next, let's obtain all nodes that describe each product ordered
doc("po.xml")//entry/product/@prod_name
|
Now, let's pull these two node sequences together to present all product names and amounts ordered by the retailer that are made by the manufacturer "ACME".
<manufacturer> { for $entry in doc("po.xml")/invoicecollection/invoice/entries/entry where $entry/product/@maker = "ACME" return <order> <quantity> {data($entry/@quantity)} </quantity> <product> {data($entry/product/@prod_name)} </product> </order> } </manufacturer> |
This XQuery FLWOR expression binds the variable $entry to each entry in the retail purchase order document, po.xml. This creates a series of tuples for each entry. Each tuple contains a single binding where $entry is a single entry in the purchase order. The where clause tests to see if each product tuple is made by the manufacturer "ACME". The return clause constructs a subsequent order that will later be sent to the manufacturer.
The resulting XML produced looks like this:
<manufacturer> <order> <quantity>2</quantity> <product>atomic hammer</product> </order> <order> <quantity>1</quantity> <product>power springs</product> </order> </manufacturer> |
We have used a simple XQuery FLWOR expression to obtain the product order quantities for the manufacture "ACME" from the purchase order.
There is one last step before we send the web message. Recall that XYZ.COM needs to maintain a minimal product inventory and must ensure that all retailer purchase orders processed are compared to the inventory database. This keeps the inventory sufficiently stocked to guarantee timely delivery to all retailers. Therefore our generated purchase order for the manufacture must take into account the XYZ.COM inventory for all atomic hammer and power springs made by "ACME".
In Lesson 4, we complete the final step. We query both our retailer purchase orders and the inventory database to ensure the correct order is sent to the manufacturer's web service.
XQuery FLWOR expressions are used to query XML data of any type including XML views of relational data.