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:printStack
for saxon:print-stack
,
or saxon:stringToBase64Binary
for 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
a user-written JavaExtensionFunctionFactory
.
In SaxonJ, the functions bin:encode-string()
and bin:decode-string()
now accept
any encoding supported by the Java VM.
In SaxonCS, the functions bin:encode-string()
and bin:decode-string()
accept
any encoding supported by the .NET method Encoding.GetEncoding()
.
New Extension Functions
Some new extension functions have been added:
-
saxon:escape-NCName() and saxon:unescape-NCName()
The function
saxon:escape-NCName()
can be used to turn any string into a validNCName
: for example"date of birth"
becomes"date_20_of_20_birth"
. This can be useful when converting JSON to XML. The functionsaxonc: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 proposedfn: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, butsaxon: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. -
Allows dynamic evaluation of XQuery expressions: it replaces the existing
saxon:compile-query()
andsaxon: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 saxon:pause-tracing()
and saxon:resume-tracing()
have
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
saxon:compile-query
, saxon:is-defaulted
, saxon:key-map
,
saxon:last-modified
, saxon:parse-dateTime
, saxon:send-mail
,
saxon:query
, saxon:unparsed-entities
.
Some EXSLT and EXPath function libraries are not implemented in SaxonCS, including the EXSLT date/time library and the EXPath archive library.
Extension Instructions
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|no"
. With composite="yes"
, the members of the new array may be arbitrary
sequences, and should be constructed using saxon:array-member (or fn:parcel()
). With
composite="no"
, the members of the array must be singletons, and are returned by the sequence constructor
as a normal sequence of items.
The 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
arrays.
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
negative: 10 by -1 to 6
returns (10, 9, 8, 7, 6)
.
The ternary conditional syntax A ?? B !! C
is implemented (it is semantically equivalent
to 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 xs:positiveInteger
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 xs:integer
then you can supply the decimal value 3.0, but you can't supply 3.1, even though casting 3.1 to xs:integer
is allowed.
XSLT extensions
An extension instruction can be used to invoke a named template. For example, a template with name x:error
with declared parameters message
and code
might be called using the instruction
<x:error message="Intoxication detected" code="ABXZ9275"/>
, in place of an xsl:call-template
instruction with multiple xsl:with-param
children. For details, see
Extension
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
xsl:item-type
declaration. -
xsl:match
Used to match selected items against an XSLT pattern; see The
xsl:match
instruction.) -
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:
-
The proposed
break-when
attribute 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@length
attributes of the elements in a group would otherwise exceed 30. For more details see Grouping usingbreak-when
. -
The proposed
array
andmap
attributes are implemented as alternatives toselect
on 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. -
The
on-duplicates
attribute is now available on a xsl:map instruction; see Controlling duplicates onxsl:map
. -
The
separator
attribute is now available on xsl:for-each and xsl:apply-templates, similar to theseparator
attribute onxsl: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.