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.

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);
      
 
 
 

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.

 
 
 
 
Note
If the context item and result document handler are the only things that are being set in the DynamicContextSettingsDynamicContextSettingsDynamicContextSettings, then we can instead use the overload of EvaluateUpdate (XPathItem, IResultDocumentHandler)EvaluateUpdate (XPathItem, IResultDocumentHandler)EvaluateUpdate (XPathItem^, IResultDocumentHandler^) that takes a context item in place of the settings.
 

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.