SAXONICA

Saxon Documentation
Full Contents
About Saxon
Changes in this Release
Conditions of Use
Using XSLT 2.0
Using XQuery
Handling Source Documents
XML Schema Processing
The XPath API
Standards Conformance
Extensibility
| Introduction
| Writing extension functions
| Converting Arguments to Extension Functions
| Converting the Result of an Extension Function
» | Writing extension instructions
| Writing input filters
| Writing output filters
| Implementing a collating sequence
| Localizing numbers and dates
| Adding an output encoding
| Writing a URI Resolver for Input Files
| Writing a URI Resolver for Output Files
Saxon Extensions
Sample Saxon Applications
The Saxon SQL Extension
XSLT Elements
XPath 2.0 Expression Syntax
Function Library
XSLT Patterns

# Writing extension instructions

Saxon implements the element extensibility feature defined in the XSLT standard. This feature allows you to define your own instruction types for use in the stylesheet. These instructions can be used anywhere within a content constructor, for example as a child of `xsl:template`, `xsl:if`, `xsl:variable`, or of a literal result element.

If a namespace prefix is to be used to denote extension elements, it must be declared in the `extension-element-prefixes` attribute on the `xsl:stylesheet` element, or the `xsl:extension-element-prefixes` attribute on any enclosing literal result element or extension element.

Note that Saxon itself provides a number of stylesheet elements beyond those defined in the XSLT specification, including `saxon:assign`, `saxon:entity-ref`, and `saxon:while`. To enable these, use the standard XSLT extension mechanism: define `extension-element-prefixes="saxon"` on the xsl:stylesheet element, or `xsl:extension-element-prefixes="saxon"` on any enclosing literal result element.

To invoke a user-defined set of extension elements, include the prefix in this attribute as described, and associate it with a namespace URI that ends in "/" followed by the fully qualified class name of a Java class that implements the `net.sf.saxon.style.ExtensionElementFactory` interface. This interface defines a single method, `getExtensionClass()`, which takes the local name of the element (i.e., the name without its namespace prefix) as a parameter, and returns the Java class used to implement this extension element (for example, `return SQLConnect.class`). The class returned must be a subclass of `net.sf.saxon.style.StyleElement`.

The best way to see how to implement an extension element is by looking at the example, for SQL extension elements, provided in package `net.sf.saxon.sql`, and at the sample stylesheet books-sql.xsl which uses these extension elements. The main methods a `StyleElement` class must provide are:

prepareAttributes() | This is called while the stylesheet tree is still being built, so it should not attempt to navigate the tree. Its task is to validate the attributes of the stylesheet element and perform any preprocessing necessary. For example, if the attribute is an attribute value template, this includes creating an Expression that can subsequently be evaluated to get the AVT's value.
validate() | This is called once the tree has been built, and its task is to check that the stylesheet element appears in the right context within the tree, e.g. that it is within a template
process() | This is called to process a particular node in the source document, which can be accessed by reference to the XPathContext object supplied as a parameter.
isInstruction() | This should return true, to ensure that the element is allowed to appear within a template body.
mayContainTemplateBody() | This should return true, to ensure that the element can contain instructions. Even if it can't contain anything else, extension elements should allow an xsl:fallback instruction to provide portability between processors

The `StyleElement` class has access to many services supplied either via its superclasses or via the XPathContext object. For details, see the API documentation of the individual classes.

Any element whose prefix matches a namespace listed in the `extension-element-prefixes` attribute of an enclosing element is treated as an extension element. If no class can be instantiated for the element (for example, because no ExtensionElementFactory can be loaded, or because the ExtensionElementFactory doesn't recognise the local name), then fallback action is taken as follows. If the element has one or more `xsl:fallback` children, they are processed. Otherwise, an error is reported. When `xsl:fallback` is used in any other context, it and its children are ignored.

It is also possible to test whether an extension element is implemented by using the system function `element-available()`. This returns true if the namespace of the element identifies it as an extension element (or indeed as a standard XSLT instruction) and if a class can be instantiated to represent it. If the namespace is not that of an extension element, or if no class can be instantiated, it returns false.

Next