System Programming Interfaces
In a number of internal interfaces, namespace URIs are now represented using the class NamespaceUri rather than String
. NamespaceUri
objects are pooled (so
the same namespace is always represented by the same object), leading to fewer object allocations (and therefore less overhead in the
garbage collector), and allowing more efficient comparison - equality testing is the dominant operation on namespace URIs.
Interfaces affected include NodeInfo, Receiver, StructuredQName,
NodeName, XPathStaticContext,
AttributeMap, and NamespaceMap. In some
cases the old interface has been retained for compatibility, but use of a NamespaceUri
is preferred.
The change may affect the handling of namespace URIs containing spaces (this is an area that has never been well defined in the W3C specifications, and is best avoided).
To convert a String
to a NamespaceUri
, use the static method NamespaceUri.of(String). For the reverse, use NamespaceUri.toString().
For SaxonJ, the Java system property SAXON_INITIALIZER
may be set to the name of a class that implements
net.sf.saxon.lib.Initializer. If the class can be loaded, it will be called during
instantiation of a new Configuration. This makes it easier to customize Saxon's behavior
when Saxon is deeply embedded in an application over which the user has no direct control. (Note, applications wishing to suppress this
are free to clear the system property.)
Most warning conditions now have specific error codes associated with them, and internal interfaces have been extended so the error code can get through to a user-supplied ErrorReporter. This makes it much easier to suppress warnings selectively. The codes used can be found in the JavaDoc for class net.sf.saxon.trans.SaxonErrorCode (or, of course, in the warning message itself). The StandardErrorReporter now has a method suppressWarning that allows a specific warning condition to be suppressed.
The ParseOptions class is now immutable; any calls such as
options.setValidationMode(V)
must be replaced with options = options.withValidationMode(V)
. This change was made
for performance reasons; we found that the code was spending a great deal of time creating and copying new ParseOptions
objects.
A potential problem that has existed for many years, but which rarely surfaces, arises when a SequenceIterator
holds external resources (for example an UnparsedTextLines
iterator, which keeps a text file open), and the iterator
is neither read to completion, nor explicitly closed. This typically occurs as a consequence of lazy evaluation. When such an iterator
is created, Saxon now uses a Java Cleaner
thread (owned by the Configuration) to close the relevant
resources as soon as the iterator is garbage-collected. This extra thread may be visible in Java monitoring output. The thread
shuts down when the Cleaner
is garbage-collected, which typically happens when the Configuration
is garbage collected; it can also be forced by calling Configuration.close()
.
Saxon's original XQuery API, in which a query is compiled using a StaticQueryContext
object
and executed using a DynamicQueryContext
object, has been gradually downgraded over
a number of releases. It remains present in the product, but should no longer be considered as
a stable public API. The sample application QueryAPIExamples.java
has now been
dropped from the release.