Saxon extensions to the W3C XSLT/XQuery specifications
Changes to existing Saxon extensions and new extensions in Saxon 11 are outlined below. This includes
extension functions and instructions in the
saxon namespace, as well as
experimental implementations for version 4.0 extensions to XPath, XSLT, and XQuery. A W3C
Community Group is working on these proposals; for more information see the QT4CG Specifications, and documentation about the Saxon
implementations at Experimental 4.0 extensions.
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 main impact is that these functions 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
saxon:string-to-base64Binary. The functions
may also be stricter about what types of arguments they accept.
Another effect of the change is that calls on these functions can no longer be customized by use of
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
Some new extension functions have been added:
saxon:escape-NCName() and saxon:unescape-NCName()
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
saxonc:unescape-NCName()reverses the operation.
Selects items from a sequence. For example
slice(("a", "b", "c"), -1)returns
"c". (The function was originally based on a proposed
fn:slice()function, but that has since diverged.)
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
//xcontains very few items, or (c) that the predicate is likely to select a high proportion of the items in the filtered sequence.
Allows dynamic evaluation of XQuery expressions: it replaces the existing
saxon:query(), which are now obsolescent.
Dropped Extension Functions
The saxon:path() function is dropped: use the standard fn:path() function instead.
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.
saxon:for-each-member instruction, introduced in Saxon 10, has been dropped. For
new alternative methods to interate over the members of an array, see Iterating over maps and
XPath Syntax Extensions
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 syntax is borrowed from Perl6.
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
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
instructions calling templates.
The syntax of match patterns is extended to make it easier to match maps and arrays, see Match patterns.
A number of proposed new instructions are available:
xsl:array and xsl:array-member
Used to construct arrays; these instructions replace the previously available saxon:array and saxon:array-member (which are now synonyms). For more details see Creating arrays.
Used to declare a name (or alias) for an item type; replaces the previously available saxon:item-type. For more details see The
Used to match selected items against an XSLT pattern; see The
Used to choose one of a number of alternative outputs, based on the value of a supplied expression; see Conditional instructions.
Some new attributes are available on existing XSLT 3.0 instructions:
break-whenattribute is now available on xsl:for-each-group. For example,
<xsl:for-each-group break-when="sum($group!@length) + $next!@length) gt 30" ...>starts a new group when the total of the
@lengthattributes of the elements in a group would otherwise exceed 30. For more details see Grouping using
mapattributes are implemented as alternatives to
selecton xsl:for-each, xsl:for-each-group, and xsl:iterate, to allow these instructions to process maps and arrays as well as sequences. For more details see Iterating over maps and arrays.
on-duplicatesattribute is now available on a xsl:map instruction; see Controlling duplicates on
separatorattribute is now available on xsl:for-each and xsl:apply-templates, similar to the
xsl:value-of. For more details see Separator attribute.
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.