System Programming Interfaces

The NodeInfo interface has changed: in place of the two iterateAxis methods (taking an integer argument to identify the required axis), there is now one method for each axis, for example iterateChildAxis and iterateDescendantAxis. For the rare cases where the required axis is not statically known, there is a static method Navigator.iterateAxis() that takes the required axis as a parameter. The change is made partly for performance reasons (it avoids the switch, and makes methods smaller, which gives the Java JIT compiler more scope for optimizations), and partly because it makes it easier to inherit implementations of specific axes from a superclass, thus improving code reuse.

The internal APIs for manipulating values of type xs:duration and xs:dayTimeDuration have changed, reflecting the fact that the seconds component is now held as a BigDecimal value.

Some deprecated methods associated with handling of xsl:message output have been removed: in class XsltController, methods setMessageFactory(), setMessageReceiverClassName(), setMessageReceiver(), makeMessageReceiver(), setMessageEmitter(), getMessageEmitter().

When xsl:message is evaluated with terminate="yes", the final TerminationException that is thrown now includes the content of that final message as a Message object. The TerminationException is available using SaxonApiException.getCause(). This also applies to transformations terminated using xsl:assert.

The Configuration class now provides a method disableFunction() that allows use of any function name to be disabled. This can be a core function, a Saxon-supplied extension function, a user-registered extension function, a constructor function: anything. The method disables static function calls (such as fn:contains()), named function references (fn:contains#2) and dynamic access using function-lookup. If it is set for a function, function-available returns false.

There have been changes to the internal representation of schema information, which may affect applications using low-level access to these data structures. A schema (that is, a collection of schema components such as element and attribute declarations, complex and simple types) is generally represented internally by a com.saxonica.ee.schema.PreparedSchema object. A component such as a complex type may exist in more than one schema: this can happen, for example, when a new schema is built by combining the types in a base schema with types referenced using xsi:schemaLocation attributes. The UserComplexType object representing such a component will be present in both schemas; but the compiled form of the type (class com.saxonica.ee.schema.CompiledComplexType, which contains among other things, the finite state automaton used to validate instances) will exist independently in both: this is affected by the presence of other components in the schema, for example additional elements in substitution groups. Because multiple schemas are now allowed, many internal methods used to navigate around schema information (for example, listing the allowed children of an element) acquire an extra parameter to identify the schema, since a component such as an element declaration is not exclusive to one schema.

Any user-written class that inherits from net.sf.saxon.lib.StandardLogger may need changing. The constructors on this class have been replaced by static factory methods, to allow them to create different subclasses (a capability which is currently used only in SaxonCS).