Network Deployment (Distributed operating systems), v8.0 > Develop and deploying applications > XML applications > Use the XML API to perform operations > Use external variables and functions > Use external variables
Use external variables with XQuery
When using an XQuery expression that uses external variables, supply (or bind) values for each variable using an XDynamicContext instance and optionally declare the types of the variables using an XStaticContext instance.
Procedure
- When preparing an XQuery expression that uses external variables, declare the types of the variables using an XStaticContext instance.
Variables declared in the XStaticContext are only visible to the main module. To make an external variable visible to a library module, it must be declared in the prolog of the library module with an external variable declaration.
Declare the variable in the XStaticContext is optional. If a variable is not declared, the processor assumes that its type is item()*. In other words, the value of the variable can be a sequence of any length consisting of items of any type. Declaring a type for your variables can help the processor detect some usage errors statically during preparation.
The XStaticContext interface has two declareVariable methods that each have two parameters—one for the name, and one for the type of the variable. The name is always provided as a QName object, but the type can be a QName or an XSequenceType.
XStaticContext declareVariable methods.
The following table explains when to use each form of the declareVariable method.
Method Signature Purpose declareVariable(QName name, QName type) Use when value of the variable is a single atomic value The QName must refer to a built-in type or a global type declared in a schema that has been registered on the XFactory instance used to create the XStaticContext instance. If the QName refers to a non-atomic type, then the processor will treat the variable as having the type element(*, ns:type), where ns:type is the given QName. The XTypeConstants interface has convenient constants available that provide a QName object for each built-in type.
declareVariable(QName name, XSequenceType type) Use when value of the variable is a single node or a sequence of atomic values or nodes XQuery also allows variables to be declared in the prolog of an XQuery expression. The following XQuery expression uses two variables, one declared in the prolog and one not.
declare namespace xs = "http://www.w3.org/2001/XMLSchema"; declare variable $searchTerms as xs:string+ external; <table> <tr> <td>Title </td> <td>Author </td> </tr> { for $book in /library/book let $value := $book/@*[local-name()=$searchField] where exists(for $term in $searchTerms return if (contains($value, $term)) then true() else ()) return <tr> <td>{ string($book/@title) } </td> <td>{ string($book/@author) } </td> </tr> } </table>The variable not declared in the XQuery expression itself can be optionally declared using an XStaticContext instance to provide the processor with type information.The following example shows how to prepare the above XQuery expression, providing a type for the variable not declared in the XQuery expression itself. It assumes that the expression is accessible using the xquerySource source object.
// Create the factory XFactory factory = XFactory.newInstance(); // Create a new static context from the factory XStaticContext staticContext = factory.newStaticContext(); // Define a QName for the name of the variable to be declared final QName searchField = new QName("searchField"); // Declare a variable called "searchField" as an xs:string staticContext.declareVariable(searchField, XTypeConstants.STRING_QNAME); // Prepare the XQuery expression XQueryExecutable xquery = factory.prepareXQuery(xquerySource, staticContext);
- To execute an XQuery expression that uses external variables, supply (or bind) values for each variable using an XDynamicContext instance.
The bindings for external variables will be available to the main module and to any library modules that have an external variable declaration in their prolog for that variable.
An error is raised if you do not supply a value for a variable used when executing the XQuery expression.
The XDynamicContext has a number of bind, bindItem, and bindSequence methods. Each has two parameters, where the first is a QName object corresponding to the name of the parameter and the second is the value.
XDynamicContext bind, bindItem, and bindSequence methods.
The following table explains when to use each form of the XDynamicContext bind, bindItem, and bindSequence methods.
Method Purpose bind Use when binding a single atomic value There is one form of this method for each of the Java types used in the standard mapping of built-in types to Java types. There are two additional forms—one that takes a node and one that takes a source. These are used for binding any node from a DOM tree and parsing a new source to yield a document node, respectively.
bindItem Use when binding a single item as an XItemView object An XItemView object can be obtained from the result of executing another expression or constructed using an XItemFactory instance.
bindSequence Use when binding sequences of less than or greater than one item There is one form of this method for each of the Java types used in the standard mapping of built-in types to Java types; each accepts an array of values the given type.
There is an additional form that takes an XSequenceCursor. An XSequenceCursor can be the result of executing another expression or can be constructed using an XItemFactory instance.
The following example executes the XQuery expression prepared in the first example, first binding values for each of the variables it uses.
// Create a new dynamic context from the factory XDynamicContext dynamicContext = factory.newDynamicContext(); // Bind an atomic value for the "searchField" variable dynamicContext.bind(searchField, "title"); // Bind a sequence of atomic values for the "searchTerms" variable dynamicContext.bindSequence(new QName("searchTerms"), new String[] {"Lost", "Gables"}); // Create an XML input document String xml = " <library>" + " <book title='Lost in the Barrens' author='Farley Mowat'/>" + " <book title='Anne of Green Gables' author='L. M. Montgomery'/>" + " </library>"; StreamSource source = new StreamSource(new StringReader(xml)); // Execute the expression XSequenceCursor result = xquery.execute(source, dynamicContext);
Use static and dynamic contexts
The XFactory class
Use sequence types
Map XML types to Java types
Navigate with XSequenceCursor
Navigate with XTreeCursor
Create items and sequences
Create items and sequences using the XItemFactory