Extensibility

A new way of implementing extension functions is available. These are known as integrated extension functions. Unlike traditional extension functions invoked as Java methods through reflexion, each integrated extension function is implemented as a separate class that extends the abstract class net.sf.saxon.functions.ExtensionFunctionDefinition, together with a class that extends net.sf.saxon.functions.ExtensionFunctionCall. The first class must implement a number of methods providing information about its argument types and result types, while the second provides the call() method which is invoked to call the function. A key advantage of this kind of extension function is that it can exercise compile-time behaviour, for example saving information about the static context in which it is called, or optimizing itself based on the expressions supplied in the function arguments. Another advantage is that you have complete control over the function name, for example you can choose any namespace you like.

Integrated extension functions need to be registered in the Saxon Configuration. You can do this via the API, or (in Saxon-PE and Saxon-EE) via the configuration file. This means that in Saxon Home Edition it is not possible to use integrated extension functions when running from the standard command line interface.

The old way of binding extension functions ("reflexive extension functions"), by mapping the namespace URI of the function name to a Java class, is not available in Saxon Home Edition. Also, it has changed so that by default, it only recognizes namespaces using the recommended format java:full.class.name. If you need to recognize arbitrary namespaces ending in the Java class name (as allowed in previous releases on XSLT, but not XQuery), find the JavaExtensionLibrary by calling Configuration.getExtensionBinder("java"), and on this object call setStrictJavaUriFormat(false).

The ExtensionFunctionFactory (which can be used to change the details of the calling mechanism for reflexive extension functions, for example to perform diagnostic tracing) is now set as a property of the JavaExtensionFunctionLibrary or DotNetExtensionFunctionLibrary, rather than directly via the Configuration.

Under .NET, if an extension function expects a value of type XdmAtomicValue, it is now possible for the calling XPath expression to supply a node; the node will be automatically atomized.

The factory mechanism for handling XSLT extension instruction namespaces has changed. Previously it was required that the namespace URI should end in the Java class name of a class implementing the ExtensionElementFactory interface. It is now possible to use any namespace URI you like. The namespace you choose must be associated with the name of the ExtensionElementFactory class in the Configuration, which you can do programmatically by calling Configuration.setExtensionElementNamespace(), or from the configuration file. Element extensibility is not available in Saxon Home Edition, which also means that the SQL extensions are not available.