Read XSLT 2.0 and XPath 2.0 Programmer's Reference, 4th Edition Online
Authors: Michael Kay
Extension Instructions
Extension instructions are elements in the Saxon namespace that perform a similar role to XSLT instructions. If you use any of these instructions, your stylesheet must contain the attribute
extension-element-prefixes=“saxon”
. You can use
Instruction | Meaning |
saxon:assign | Modifies the value of a variable. Not recommended, as the effect can be very unpredictable. |
saxon:call-template | Same as |
saxon:doctype | Constructs a DTD to include in the output document. |
saxon:entity-ref | Creates an entity reference in the serialized output. |
Saxon also provides a set of extension instructions
sql:connect
,
sql:query
,
sql:insert
,
sql:delete
, and
sql:update
, allowing data to be read from and written to relational databases. These are in the namespace
/net.sf.saxon.sql.SQLElementFactory
and are described at
http://www.saxonica.com/documentation/sql-extension/intro.html
.
Extension Functions
The largest category of extensions are additional functions provided in the Saxon namespace. Chapter 16 contains advice on how to call extension functions without sacrificing portability of your stylesheet.
Examples of these functions are shown in the table below, grouped according to their intended purpose. Some of them are available only in Saxon-SA.
Functions | Purpose |
saxon:parse() saxon:serialize() saxon:compile-stylesheet() saxon:transform() | Allow parsing, serialization, and transformation of documents to be controlled from within a stylesheet. Useful when input or output documents contain nested documents within CDATA sections. |
saxon:analyze-string() saxon:for-each-group() saxon:format-date() saxon:format-number() saxon:generate-id() saxon:index() saxon:find() saxon:namespace-node() etc. | Provide equivalents of XSLT capabilities for the benefit of XQuery users. |
saxon:base64Binary-to-octets() saxon:base64Binary-to-string() saxon:hexBinary-to-octets() saxon:hexBinary-to-string() | Allow manipulation of base64 binary values (found for example in LDAP directories) and hexBinary values. |
saxon:path() saxon:line-number() saxon:system-id() saxon:type-annotation() | Provide information about the current node in the source document, for use in diagnostics. |
saxon:try() | Allows dynamic errors to be caught. |
saxon:eval() saxon:evaluate() saxon:evaluate-node() saxon:expression() | Allow evaluation of XPath expressions constructed dynamically from strings or read from a source document. See next section for a use case. |
The evaluate() Extension
Many of the new facilities included in XSLT 2.0, including multiple output files, grouping facilities, and stylesheet functions, were first pioneered as Saxon extensions. Saxon also copied extensions that were first introduced elsewhere: the ubiquitous
node-set()
extension function, for example, appeared first in James Clark's xt processor, as did extensions to find the intersection or difference between two node-sets. Saxon went further than most XSLT processors in providing a wide range of extensions built in to the product. However, most of these have been superseded by standard features in XSLT 2.0.
The most important extension that remains, which has sadly not made it into XSLT 2.0 even though it has been copied by several other processors, is the ability to evaluate a dynamically constructed XPath expression. This extension has been adopted, in restricted form, as the
dyn:evaluate()
function within EXSLT (see
www.exslt.org
). Here I will describe the Saxon implementation of this functionality.
In standard XSLT (even in 2.0), there is no way of constructing an XPath expression at runtime from a string. This makes it difficult to do things that are very familiar to SQL programmers; for example, building a query from the values of parameters read from a form, or sorting a table on a column selected by the user. It also makes it impossible to interpret XPath expressions held as part of the text of the source document, perhaps implementing a subset of the XPointer specification for defining links between documents. The Saxon stored expression concept fills this gap: you can use the
saxon:expression()
extension function to create a stored expression from a string, and
saxon:eval()
to evaluate the stored expression; or you can combine these two operations into one using the
saxon:evaluate()
function.
The table below describes these functions in more detail.
Function | Explanation |
expression(string) | This function constructs a stored expression from the XPath expression contained in the supplied string. The stored expression can be evaluated later using the saxon:eval() function. |
If the XPath expression contains namespace prefixes, these are resolved at the time the stored expression is created, not at the time it is subsequently evaluated. They are always resolved relative to namespaces declared in the stylesheet. | |
The expression may contain references to the variables $p1 to $p9 . The values of these variables are supplied when the expression is subsequently evaluated. | |
eval(expression, variables...) | This function evaluates a stored expression supplied in the first argument. The stored expression is constructed using the saxon:expression() function. The second and subsequent arguments (which are optional) provide values that will be bound to the variables |
The context node, position, and size for evaluating the expression are those that apply to the stylesheet at the point where eval() is called. | |
evaluate(string, variables...) | This function combines the effect of saxon:expression() and saxon:eval() into a single call: That is, it prepares the expression and immediately evaluates it. |
evaluate-node(node) | This function can be used when reading an XPath expression stored in a source XML document. It is similar to saxon:evaluate() , except that namespace bindings are taken from the node where the expression is written, rather than from the stylesheet; this node is also used as the context node. This version does not allow reference to parameters. |
Allowing XPath queries to be constructed dynamically gives a number of benefits: