XQJ (JSR 225) interface
Saxon's implementation of XQJ has been brought into line with the 1.0 "final draft" released on 20 Nov 2007. The final draft includes a set of compatibility tests, and Saxon now passes all these tests, with the exception of four tests whose results have been queried as they appear inconsistent with the documentation.
This change means that the XQJ interfaces now have their proper package names (
in place of
net.sf.saxon.javax.xml.query.*, and applications will need to be updated accordingly.
The interfaces together with the implementation classes are in the JAR file saxon9-xqj.jar .
To pass the test suite, quite a few changes were necessary, but few of these will affect applications. Many of them concern the error behaviour when null arguments are passed to methods, or when operations are attempted on a connection that has been closed - neither of which are things that real applications are likely to do.
One more noticeable change is that the rules for processing a forwards-only sequence are now strictly enforced. These
rules prevent you accessing the same item in the result of a query more than once, unless you save a local copy using
As required by the licensing conditions for XQJ, a conformance statement is provided.
The XQJ implementation now allows a Java object to be supplied as an "external object", whose instance methods
can be invoked as external functions within the query. TestL in the sample application
XQJExamples.java provides an
illustration of how to do this. It is necessary to create an
XQItemType representing the type of the
item: this will always have a name whose URI is
http://saxon.sf.net/java-type and whose local name
is the qualified name of the Java class. The standard XQJ method
createItemFromObject() will recognize a
type name in this form and handle the object accordingly.
A number of named properties have been implemented to allow Saxon's behavior to be configured via the
setProperty() method of
XQDataSource; for details see the Javadoc of the
Saxon implementation class
SaxonXQDataSource. For configuration settings that are not in this
SaxonXQDataSource provides a method
getConfiguration() that allows access
to the underlying
A Saxon-specific method has been added to the
SaxonXQConnection class, which is Saxon's
XQConnection. The method
copyPreparedExpression() allows an
XQPreparedExpression created under one connection to be copied to a different connection. This
makes it much easier to compile a query once and run in concurrently in multiple threads, a facility that is
notoriously absent from the XQJ specification. When a prepared expression is copied in this way, the compiled code
of the query and the static context are shared between the two copies, but each copy has its own dynamic
context (for query parameters and suchlike).
There have been changes to the implementation of XQJ methods involving input or delivery of results using
XMLStreamReader interface. These methods are now implemented using the "pull events"
mechanism introduced in Saxon 9.0, replacing the older
EventIterator is available for use in the event-pull pipeline, namely
This maintains the namespace context (it acts as a
NamespaceResolver). This is used by XQJ when delivering
results in the form of a StAX
XMLStreamReader, underpinning the methods on the
interface that allow namespace prefixes to be resolved.