XSLT 4.0 implementation

Saxon 13 outputs SEF files that can be imported by Saxon 13. We have not tested whether these SEF files can be imported by Saxon 12 or by SaxonJS 2 or 3, and we have not tested whether SEF files generated by Saxon 12 can be imported by Saxon 13. These questions are likely to be addressed in future maintenance releases.

New features from the 4.0 specifications

Many new features from the draft 4.0 specifications are implemented in Saxon 13, and they are not all listed individually here. In general, to check whether a new feature is implemented:

  1. Check the blue change entries in the draft specifications listed at qt4cg.org. In most cases these link to the GitHub issues and pull requests (PRs) that record the progress of each change. For example, section 5.5 of the XSLT 4.0 specification starts with the change entry:

    The strings used in the formatted number to represent a decimal separator, grouping separator, exponent separator, percent sign, per mille sign, or minus sign, are no longer constrained to be single characters. [Issue 1048 PR 1250 3 June 2024]
  2. Click on the PR number in the spec to find the relevant PR on GitHub. For this example (at the time of writing) the PR carries the labels "Completed", "Tests Added", and "In Saxon13", confirming that the feature is fully implemented and tested in Saxon 13. Be aware, however, that the 4.0 specifications are work in progress, and that the specification and implementation are both subject to change.

References of the form PR nnnn refer to pull requests against the specifications in GitHub.

XSLT 4.0 changes

The XSLT-specific function fn:character-map is implemented.

The xsl:sequence instruction now allows an @as attribute.

xsl:include declarations now allow cycles and "diamond" structures: if the same module is included more than once at the same stylesheet (import) level, all but the first xsl:include declarations are ignored.

Enclosed modes are implemented (a mode in which the xsl:template rules appear as children of the xsl:mode element).

The experimental attribute break-when for xsl:for-each-group is renamed split-when in XSLT 4.0; for the time being break-when is retained as a synonym.

At the time of first release of Saxon 13, there has been some flux in the draft 4.0 specifications regarding the processing of arrays using template rules. The array:members function represents each array member as a "value record" (a map with a single entry having the key "value"), while the xsl:array-member instruction originally represented an array member as a zero-arity function item; the representation changed more recently to use a JNode. The current implementation of xsl:array-member in Saxon generates a zero-arity function item, while xsl:array accepts either a zero-arity function item or a value record. Most simple use cases for these instructions are unaffected by the detailed representation; however, this situation is unstable and further changes can be expected in this area.

Constructing an array with xsl:array using the new for-each attribute is currently only partially implemented in Saxon. The specification says that "when the for-each attribute is present, then it is not necessary to use the xsl:array-member instruction". However in Saxon 13.0, when using the for-each attribute, the members must explicitly be parcels, constructed using the xsl:array-member instruction.

In the current 4.0 specification, an XSLT match pattern of the form match="order" is defined to match both an element node with node-name "order", and a JNode with selector value "order". This has proved troublesome from an implementation viewpoint (it affects type-checking and streamability analysis) and it's not especially intuitive: Saxonica has therefore proposed a change to the specification. In the meantime, in Saxon 13, the pattern match="order" will only match element nodes. JNodes can be matched using a pattern of the form match="~jnode(order)".

The duplicates attribute of xsl:map is implemented.

The xsl:select instruction is implemented.

4.0 Features not yet implemented

Here is a list of some of the features in the 4.0 specifications that have NOT yet been implemented. Please check the QT4 GitHub project (https://github.com/qt4cg/qtspecs) for the latest status: Pull Requests are labeled "In Saxon13" when they have been implemented.