In one of my previous posts, I blogged about the new W3C XML Query publications, including XQuery Update Facility.
Talking to people, I feel a majority relate XQuery Update Facility with updating XML documents in some persistent store. But there is actually more, it is also about transforming and enriching (transient) documents. In fact a use case hard to handle with XQuery 1.0.
Note the XQuery Update Facility is today in W3C Candidate Recommendation status. Although not yet supported by DataDirect XQuery, we are following the progression of the specification closely, and hope to communicate about our plans soon, when the specification moves into Proposed Recommendation status.
Anyway, I want to give a feel on what will be possible in the near future.
Let’s consider a concrete example. Not so long ago I posted a series on XQuery generating multiple XML documents, let’s continue with this theme. Assume you have a directory with XML documents, and these need to be enriched with data coming out of your relational database. For example, orders need to be completed with the shipping address.
Let’s enrich all our orders, each a separate XML document. Using the customer’s name available in the order, we lookup the shipping address in our relational database and enrich subsequently the order with that shipping address.
In the margin, we use the utility function
local:get-file-name
, which we introduced before.
[cc lang="xquery"]for $order in fn:collection("file:///C:/inputorders?select=*.xml") let $filename := concat("file:///C:/outputorders/", local:get-file-name(document-uri($order))) let $newOrder := { $order/order/customer,
{ fn:collection("CUSTOMERS")/CUSTOMERS[NAME = $order/order/customer]/ADDRESS/text() }
, $order/order/totalprice, $order/order/priority, $order/order/deliverydate, $order/order/notes, $order/order/lineitems } return ddtek:serialize-to-url($newOrder, $filename, "") [/cc]
Basically we read information out of the input document, and recreate the output using the same structure, but extending it with the shipping address. There are a number of issues with such approach.
- The more complex the input documents are, the more complex and longer the query will be.
- The query is specific to the document structure. When the document structure evolves, the query needs to be updated.
- If you need to handle different document types, either your query becomes more complex or multiple queries are to be used.
And as you can imagine, the more complex your documents are, the more these issues are relevant. The example above is in fact over simplified. Typical XML documents in the industry are much more complex, think for example on some of the ones we use in our tutorial How DataDirect XQuery Helps the Insurance Industry Deal with ACORD Standards.
Using XQuery Update Facility this becomes much simpler. It helps to resolve the raised concerns, resulting in more maintainable queries, and eventually increased productivity.
In the following query we simply enrich all XML documents by adding a corresponding address element after each customer element. Such approach is much more robust, and is ready to handle future revisions of the orders XML Schema.
[cc lang="xquery"]for $order in fn:collection("file:///C:/inputorders?select=*.xml") let $filename := concat("file:///C:/outputorders/", local:get-file-name(document-uri($order))) return copy $newOrder := $order modify insert node
{ fn:collection("CUSTOMERS")/CUSTOMERS[NAME = $order/order/customer]/ADDRESS/text()}
after $newOrder/order/customer return ddtek:serialize-to-url($newOrder, $filename, "")[/cc]
Queries like the above one are already fully functional in our development lab. At DataDirect we are excited about all the new functionality the XQuery Update Facility will bring to the XML development community.