Using XQuery Update Facility 1.0
This guide explains how to use XQuery Update Facility 1.0 with XmlPrime.
This topic contains the following sections.
- Loading the Input Document
- Compiling an Updating Query
- Executing the Query
- Accessing updated documents.
- Multiple results.
The XQuery Update Facility 1.0 is engaged by default when using the XQueryXQueryXQuery class. It can be disabled via the EnabledFeaturesEnabledFeaturesEnabledFeatures property.
Loading the Input Document
In this example we will be using the bstore1.example.com/bib.xml document as described in XML Query Use Cases. The document is as follows:
<bib> <book year="1994"> <title>TCP/IP Illustrated</title> <author><last>Stevens</last><first>W.</first></author> <publisher>Addison-Wesley</publisher> <price>65.95</price> </book> <book year="1992"> <title>Advanced Programming in the Unix environment</title> <author><last>Stevens</last><first>W.</first></author> <publisher>Addison-Wesley</publisher> <price>65.95</price> </book> <book year="2000"> <title>Data on the Web</title> <author><last>Abiteboul</last><first>Serge</first></author> <author><last>Buneman</last><first>Peter</first></author> <author><last>Suciu</last><first>Dan</first></author> <publisher>Morgan Kaufmann Publishers</publisher> <price>39.95</price> </book> <book year="1999"> <title>The Economics of Technology and Content for Digital TV</title> <editor> <last>Gerbarg</last><first>Darcy</first> <affiliation>CITI</affiliation> </editor> <publisher>Kluwer Academic Publishers</publisher> <price>129.95</price> </book> </bib>
This document is assumed to be in the file bib.xml.
To query the document, we load it into an XdmDocumentXdmDocumentXdmDocument. For more information about document representations, see Document Representations. We will store it in a DocumentSetDocumentSetDocumentSet, and it will be to this document set that the updated document is written.
DocumentSet documentSet = new DocumetSet(); var document = new XdmDocument("bib.xml", XmlSpace.Preserve); documentSet.Add(document);
Compiling an Updating Query
We will run the following query over our document, which increases the prices of all books.
for $price in /bib/book/price return replace value of node $price with $price * 1.1
The next stage is to compile the query. To escribe how the
query should be compiled we need set up an
XQuerySettingsXQuerySettingsXQuerySettings
object. This describes all the settings used for compilation. In
particular, we will set the context item type. By default
the context item type is set to none
, and so
the context item cannot be set unless we override the type here.
We can then compile the query using the
CompileCompileCompile
method. This returns us an
XQueryXQueryXQuery object
encapsulating the query.
XQuerySettings querySettings = new XQuerySettings(nameTable); querySettings.ContextItemType = XdmType.Node; string program = "for $price in /bib/book/price" + "return replace value of node $price)" + "with $price * 1.1"; XQuery query = XQuery.Compile(program, querySettings);
An XQueryX query can be compiled by passing an IXPathNavigableIXPathNavigableIXPathNavigable instance over the XQueryX document to the XQuery.Compile (IXPathNavigable, XQuerySettings)XQuery.Compile (IXPathNavigable, XQuerySettings)XQuery::Compile (IXPathNavigable^, XQuerySettings^) method.
In this example, we are going to assume that the query is an updating query. Therefore we know that the static type of the query will be the empty sequence and that it will generate a "pending update list" of updates to apply at the end of the query. We can check that this is the case by examining the IsUpdateIsUpdateIsUpdate property of the XQueryXQueryXQuery class.
if (query.IsUpdate == false) throw new NotSupportedException("Sorry, updates only please!");
Executing the Query
Now we have our query object we now just need to evaluate it. We use the DynamicContextSettingsDynamicContextSettingsDynamicContextSettings which describes the parameters used to evaluate the query. In particular we will set the context item to be the document that we loaded earlier.
XPathNavigator contextItem = document.CreateNavigator(); DynamicContextSettings settings = new DynamicContextSettings(); settings.ContextItem = contextItem;
Next we need to create a result document handler, which is responsible for handling updated documents and calls to
the updating XQuery function fn:put
. This is a class implementing the
IResultDocumentHandlerIResultDocumentHandlerIResultDocumentHandler interface. For this example, the updated
document will be written back to the DocumentSetDocumentSetDocumentSet. The document set
provides a method DocumentSet.CreateResultDocumentHandlerDocumentSet.CreateResultDocumentHandlerDocumentSet::CreateResultDocumentHandler which creates
an instance for this purpose.
All that remains is to execute the query, using the XQuery.EvaluateUpdate (DynamicContextSettings, IResultDocumentHandler)XQuery.EvaluateUpdate (DynamicContextSettings, IResultDocumentHandler)XQuery::EvaluateUpdate (DynamicContextSettings^, IResultDocumentHandler^) method and passing the DynamicContextSettingsDynamicContextSettingsDynamicContextSettings we created earlier, and the IResultDocumentHandlerIResultDocumentHandlerIResultDocumentHandler provided by the document set.
using (var resultDocumentHandler = documentSet.CreateResultDocumentHandler()) { query.EvaluateUpdate(settings, resultDocumentHandler); resultDocumentHandler.Complete(); }
The call to IResultDocumentHandler.CompleteIResultDocumentHandler.CompleteIResultDocumentHandler::Complete indicates that all updates have been completed and that updated or newly created documents should be written back to the document set. If an exception had been raised during query processing, all updated or newly created documents would be discarded when the result document handler is disposed.
Accessing updated documents.
Upon successful completion of an update, updated documents must be re-retrieved from the document set. That is,
document
continues to reference the document prior to the update.
Multiple results.
When a query uses the fn:put
updating function, a query can create more than one result.
These additional results are handled via the IResultDocumentHandlerIResultDocumentHandlerIResultDocumentHandler
interface. Overloads of the
XQuery.EvaluateXQuery.EvaluateXQuery::Evaluate,
XQuery.EvaluateUpdateXQuery.EvaluateUpdateXQuery::EvaluateUpdate
and
XQuery.SerializeXQuery.SerializeXQuery::Serialize
methods which take a IResultDocumentHandlerIResultDocumentHandlerIResultDocumentHandler should be used to handle calls
to fn:put
. Other overloads will raise an exception if a call to fn:put
is encountered.