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 saxon:printStack for saxon:print-stack, or saxon:stringToBase64Binary for saxon:string-to-base64Binary.

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

The function saxon:xquery() allows dynamic evaluation of XQuery expressions: it replaces the existing saxon:compile-query() and saxon:query(), which 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.

Added saxon:slice(). 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.)

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 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.

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 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

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 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

Implemented xsl:for-each-group break-when="expression". 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.

Implemented the proposed array and map attributes as alternatives to select on xsl:for-each, xsl:iterate, and 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.