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 XPath
When using an XPath 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 XPath expression that uses external variables, declare the types of the variables using an XStaticContext instance.
This step is optional. If a variable is not declared, the processor assumes 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 The following example shows how to prepare an XPath expression that uses variables, with two declared in the static context and one not declared.
// Create the factory XFactory factory = XFactory.newInstance(); // Create a new static context from the factory XStaticContext staticContext = factory.newStaticContext(); // Define QNames for the names of the variables to be declared final QName taxRate = new QName("taxRate"); final QName partNumbers = new QName("partNumbers"); // Declare a variable called "taxRate" as an xs:float staticContext.declareVariable(taxRate, XTypeConstants.FLOAT_QNAME); // Obtain an XSequenceTypeFactory instance from the factory XSequenceTypeFactory typeFactory = factory.getSequenceTypeFactory(); // Define a sequence type for a sequence of xs:integer values XSequenceType integerSequence = typeFactory.atomic(XTypeConstants.INTEGER_QNAME, XSequenceType.OccurrenceIndicator.ZERO_OR_MORE); // Declare a variable called "partNumbers" as a sequence of xs:integer values staticContext.declareVariable(partNumbers, integerSequence); // Create an XPath expression that uses the declared variables, as well as another variable "discount" // that the processor will assume has type item()* String expression = "sum(for $partNumber in $partNumbers return /inventory/part[@num=$partNumber]/@price) * (1 - $discount) * (1 + $taxRate)"; // Prepare the XPath expression XPathExecutable xpath = factory.prepareXPath(expression, staticContext);
- To execute an XPath expression that uses external variables, supply (or bind) values for each variable using an XDynamicContext instance.
An error is raised if you do not supply a value for a variable used when executing the XPath 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 XPath 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 "taxRate" and "discount" variables dynamicContext.bind(taxRate, 0.13f); dynamicContext.bind(new QName("discount"), 0.40); // Bind a sequence of atomic values for the "partNumbers" variable dynamicContext.bindSequence(partNumbers, new int[] {2, 1, 2, 3, 2}); // Create an XML input document String xml = " <inventory>" + " <part num='1' price='9.99'/>" + " <part num='2' price='4.47'/>" + " <part num='3' price='12.99'/>" + " </inventory>"; StreamSource source = new StreamSource(new StringReader(xml)); // Execute the expression XSequenceCursor result = xpath.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