This package provides an API for executing XQuery queries directly from a Java application. It also includes the internal supporting code that implements XQuery within Saxon.
For details of the API, see the JavaDoc documentation of individual classes, starting
The first thing you need to do is to create a
This holds values of all the system settings, corresponding to flags available on the command line.
You don't need to set any properties in the
Configuration object if you are happy
with the default settings. For schema-aware processing, you will need to create a
Then you need to create a
StaticQueryContext object. As the name
implies, this holds information about the static (compile-time) context for a query. Most aspects
of the static context can be defined in the Query Prolog, but this object allows you to initialize
the static context from the application instead if you need to. Some of the facilities provided are
very much for advanced users only, for example the ability to declare variables and functions, and
the ability to specify a NamePool to be used. One aspect of the static context that you may need
to use is the ability to declare collations. Using the method
declareCollation you can
create a mapping between a collation URI (which can then be used anywhere in the Query) and a Java
StringCollator object used to implement that collation.
Having created, and possibly configured, the
StaticQueryContext objects, you can now compile a Query using the
method on the
StaticQueryContext. The text of the
Query can be supplied either as a
String or as a Java
are thus two different
compileQuery methods. Each of them returns the compiled
query in the form of a
XQueryExpression, as you would expect,
can be executed repeatedly, as often as you want, in the same or in different threads.
Before you run your query, you may want to build one or more trees representing
XML documents that can be used as input to your query. You don't need to do this: if the query
loads its source documents using the
doc() function then this will be done
automatically, but doing it yourself gives you more control. A document node at the root of
a tree is represented in Saxon by the
StaticQueryContext provides a convenience method,
that allows an instance of
DocumentInfo to be constructed. The input parameter to
this is defined by the class
javax.xml.transform.Source, which is part of the
standard Java JAXP API: the
Source interface is an umbrella for different kinds of
XML document source, including a
StreamSource which parses raw XML from a byte
or character stream,
SAXSource which takes the input from a SAX parser (or an
object that is simulating a SAX parser), and
DOMSource which provides the input
from a DOM. Saxon also provides a
net.sf.saxon.jdom.DocumentWrapper which allows
the input to be taken from a JDOM document.
To execute your compiled query, you need to create a
that holds the run-time context information. The main things you can set in the run-time context are:
setParameter()method. The mappings from Java classes to XQuery/XPath data types is the same as the mapping used for the returned values from an external Java method call, and is described under Result of an Extension Function.
setContextNode(). For some reason it isn't possible to set a context item other than a node.
You are now ready to evaluate the query. There are several methods on the
object that you can use to achieve this. The
evaluate() method returns the result sequence
as a Java
evaluateSingle() method is suitable when you know
that the result sequence will contain a single item: this returns this item as an Object, or returns null
if the result is an empty sequence. There is also an
iterator method that returns an iterator
over the results. This is a Saxon object of class
net.sf.saxon.SequenceIterator: it is similar
to the standard Java iterator, but not quite identical; for example, it can throw exceptions.
evaluateSingle() methods return the result as a Java object
of the most appropriate type: for example a String is returned as a
boolean as a
java.lang.Boolean. A node is returned using the Saxon representation of a node,
net.sf.saxon.om.NodeInfo. With the standard and tinytree models, this object also implements
Node interface (but any attempt to update the node throws an error).
iterator() method, by contrast, does not do any conversion of the result. It is returned
using its native Saxon representation, for example a String is returned as an instance of
sf.net.saxon.value.StringValue. You can then use all the methods available on this class
to process the returned value.
If you want to process the results of the query in your application, that's all there is to it. But you may want to output the results as serialized XML. Saxon provides two ways of doing this: you can produce wrapped output, or raw output. Raw output works only if the result consists of a single document or element node, and it outputs the subtree rooted at that element node in the form of a serialized XML document. Wrapped output works for any result sequence, for example a sequence of integers or a sequence of attribute and comment nodes; this works by wrapping each item in the result sequence as an XML element, with details of its type and value.
To produce wrapped output, you first wrap the result sequence as an XML tree, and then serialize the tree. To produce unwrapped output, you skip the wrapping stage and just call the serializer directly.
Both steps can be done using the
QueryResult class. This class doesn't need to be
instantiated, its methods are static. The method
QueryResult.wrap takes as input the iterator
produced by evaluating the query using the
iterator() method, and produces as output
DocumentInfo object representing the results wrapped as an XML tree. The method
QueryResult.serialize takes any document or element node as input, and writes it to
a specified destination, using specified output properties. The destination is supplied as an object
javax.xml.transform.Result. Like the
Source, this is part of the
JAXP API, and allows the destination to be specified as a StreamResult (representing a byte stream or
character stream), a SAXResult (which wraps a SAX ContentHandler), or a DOMResult
(which delivers the result as a DOM). The output properties are used only when writing to
a StreamResult: they correspond to the properties available in the
for XSLT. The property names are defined by constants in the JAXP
net.sf.saxon.event.SaxonOutputKeys for Saxon extensions): for details of the
values that are accepted, see the JavaDoc documentation or the JAXP specification.
Michael H. Kay
9 February 2005