Using s9api for XQuery
You can perform a query using the s9api interface as follows:
-
Create a Processor and set any global configuration options on the
Processor
. If the query needs any Saxon-PE or Saxon-EE features, use the constructornew Processor(true);
. -
Optionally, build the source document by calling
newDocumentBuilder()
to create a document builder, setting appropriate options, and then calling thebuild()
method. This returns an XdmNode which can be supplied as input to the query either as the context item, or as the value of an external variable. -
Call
newXQueryCompiler()
to create an XQueryCompiler. Then set any options that are local to a specific compilation (for example, the destination of error messages, the base URI, or the character encoding of the query text). -
Call one of the
compile()
methods to compile a query. The result is anXQueryExecutable
, which can be used as often as you like in the same thread or in different threads. -
To run a query, call the
load()
method on theXQueryExecutable
. This creates an XQueryEvaluator. TheXQueryEvaluator
can be serially reused, but it must not be shared across multiple threads. Set any options required for the specific query execution (for example, the initial context node, the values of external variables, and the destination for the query result), and then call either theiterator()
or therun()
method to execute the query. -
Because the
XQueryEvaluator
is anIterable
, it is possible to iterate over the results directly using the Java "for-each" construct. The result of the
XQueryEvaluator.run()
method is anXdmValue
. From 9.9 Saxon provides powerful facilities to process anXdmValue
using Java 8 streams. For example, if the query returns a single nodesection
,(XdmNode
is a subclass ofXdmValue
), then you could test whether it has any descendantpara
elements with@class="normal"
by writingif (section.select(descendant("para").where(eq(attribute("class"), "normal")).exists()) {...}
.
The output of the query may be retrieved as an iterator over a sequence of items, or it
may be specified as a Destination object, which allows a wide range of possibilities: you can send the
output to a serializer, or to a SAX ContentHandler
. You can build a tree
either in Saxon's native format (represented by the s9api class XdmNode
) or
as a DOM. You can send the output to be validated against a schema by nominating a SchemaValidator as the
destination, or you can pipe it through an XSLT transformation, because XsltTransformer also
implements the Destination
interface.
Examples of s9api queries are included in the saxon-resources
file, see
module S9APIExamples.java.
Separate compilation of library modules
Under Saxon-EE, it is possible to compile library modules separately from the main
module. This reduces the compilation time and memory usage when the same library module
is imported by many main modules for different queries. A method
compileLibrary()
(with a number of overloaded variants supplying the
input in different ways) is provided in the XQueryCompiler
class; any
library module compiled using this method will be available to all subsequent
compilations using the same XQueryCompiler
. To import the module, simply
use import module
specifying the module URI in the normal way. It is not
necessary to supply a module location hint (at "URI"
), and if any is
supplied, it will be ignored.