Saxon extensions to the W3C XSLT/XQuery specifications
Changes to Extension Functions
Many of the extension functions in the
saxon namespace have been re-implemented
as integrated extension functions where they were previously reflexive extension functions.
The only noticeable effect should be that they now enforce the specification more strictly. In
particular, the function name must be spelled as specified; it is no longer possible to use
alternative spellings such as
In SaxonJ, the functions
bin:decode-string() now accept
any encoding supported by the Java VM.
In SaxonCS, the functions
any encoding supported by the .NET method
New Extension Functions
The function saxon:xquery() allows dynamic evaluation of
XQuery expressions: it replaces the existing
are now obsolescent.
The new function saxon:unindexed() returns the value of
its argument unchanged, and a static call will normally be optimized away. The purpose of the function is to suppress
optimization of a contained filter expression: for example
//x[@y=$z] in Saxon-EE would normally be
optmized by building an index, but
saxon:unindexed(//x[@y=$z]) suppresses this optimization. This may be
useful if it is known, for example, (a) that the expression will not be evaluated often enough to justify the cost of
index construction, or (b) that the sequence
//x contains very few items, or (c) that the predicate is
likely to select a high proportion of the items in the filtered sequence.
slice(("a", "b", "c"), -1) returns
(The function was originally based on a proposed
fn:slice() function, but that has since
The function saxon:escape-NCName() can be used to
turn any string into a valid
NCName: for example
"date of birth" becomes
"date_20_of_20_birth". This can be useful when converting JSON to XML. The function saxon:unescape-NCName() reverses the operation.
Dropped Extension Functions
The undocumented and untested functions
been dropped. (The underlying methods in the Controller class remain
available if required).
A number of extension functions in the Saxon namespace have not been carried forward to the SaxonCS
product, either because they are obsolete, or because implementation is non-trivial. These include
Some EXSLT and EXPath function libraries are not implemented in SaxonCS, including the EXSLT date/time library and the EXPath archive library.
The saxon:array instruction has changed to work the
same way as the proposed XSLT 4.0
xsl:array instruction: it has an attribute
composite="yes", the members of the new array may be arbitrary
sequences, and should be constructed using saxon:array-member (or
composite="no", the members of the array must be singletons, and are returned by the sequence constructor
as a normal sequence of items.
XPath Syntax Extensions
These extensions are all experimental, and may change as a result of community standardisation efforts.
The range expression
A to B has been extended to allow
A by S to B, for example
1 by 3 to 10 returns
(1, 4, 7, 10). The step may be
10 by -1 to 6 returns
(10, 9, 8, 7, 6).
The ternary conditional syntax
A ?? B !! C is implemented (it is semantically equivalent
if (A) then B else C).
The Tuple type construct
tuple(x,y,x) is now renamed
record(x,y,z), though the old keyword is retained for
compatibility. The flag "?" after a field name, indicating that the field is optional, is now implemented; permitting
an empty sequence is no longer enough to make the field optional.
The function conversion rules (which determine how the supplied value for a function argument or XSLT variable can differ
from the declared type) now allow downcasting. For example, if the required type is declared as
then the supplied value can be
42: there is no longer any need for the caller to cast it as
xs:positiveInteger(42). Of course, an error occurs if the cast fails. The effect of this is to make
derived types such as
xs:positiveInteger much more usable. Note that this rule doesn't allow any
casting operation, only a strict relabelling of the supplied value. For example, if the required type is
then you can supply the decimal value 3.0, but you can't supply 3.1, even though casting 3.1 to
These extensions are all experimental, and may change as a result of community standardisation efforts. They are based on proposals for an XSLT version 4.0, but they do not necessarily correspond precisely with the current draft of that proposal.
An extension instruction can be used to invoke a named template. For example, a template with name
with declared parameters
code might be called using the instruction
<x:error message="Intoxication detected" code="ABXZ9275"/>, in place of an
instruction with multiple
xsl:with-param children. For details, see
Extension Instructions Calling Templates
xsl:for-each-group break-when="expression". For example,
break-when="sum($group!@length) + $next!@length) gt 30" ...> starts a new group when the total of the
attributes of the elements in a group would otherwise exceed 30.
Implemented the proposed
map attributes as alternatives to
xsl:for-each-group, to allow these instructions
to process maps and arrays as well as sequences.
Implemented the proposed
xsl:match instruction to match selected items against an XSLT pattern.
In general, streamability of new constructs introduced beyond XSLT 3.0 has not been addressed in the specification or
in testing. Constructs that are handled purely at compile time (such as the ternary operator
A ?? B !! C)
should work without problems, but constructs requiring run-time support will generally not be streamable.