What is new in XSLT 3.0

New instructions and declarations

Along with all XSLT 1.0 and XSLT 2.0 constructs, the following constructs are new in XSLT 3.0 and are fully supported:

  • <xsl:package> can be used to declare a package manifest or as alternative for a more type-safe stylesheet with declared-modes.
  • <xsl:use-package> is the equivalent of import or use in other programming languages and takes a name and version of a (precompiled) package. After using a package, you can choose to accept with <xsl:accept> what parts you want to use, or simply use all components.
  • <xsl:override> is the XSLT instruction to override used components, similar, but not the same as overriding inherited members in object-oriented languages.
  • <xsl:iterate>, which allows you to iterate over a sequence similar to <xsl:for-each>, but with extra features for handling accumulated values and the last iteration through <xsl:on-completion>.
  • Structured error handling and recovery is possibly by wrapping your code inside an <xsl:try> and <xsl:catch> block.
  • <xsl:mode> can be used to declare modes with options on how to handle non-matching nodes or items through on-no-match, which takes values deep-copy, shalow-copy, deep-skip, shallow-skip, text-only, and fail, which makes it unnecessary to create an identity-template or construct a shallow-skip delete pattern.
  • <xsl:on-empty> and <xsl:on-non-empty> make it easier to construct content when the result would otherwise have been empty, particularly useful in building tables of data.
  • <xsl:where-populated> will only construct its contents if the lead element contains actual children, i.e. is populated. This simplifies development of lists and tables.
  • <xsl:stream> introduces support for streamed processing of an input document. Using this instruction requires its content and any used modes or functions to be guaranteed streamable. The processor reports it if it isn't.
  • <xsl:merge> can be used for merging multiple input documents or streams together.
  • <xsl:accumulator> is a top-level declaration to define accumulators that can calculate an accumulated value based on whether or not a node matches a certain pattern. It allows for a less complex programming model when you need to calculate sums or averages through a myriad of otherwise tunneled parameters. It also helps with streaming for otherwise very hard to solve programming problems.
  • <xsl:fork> was added to split a single stream into multiple streams, which allows certain scenarios in streaming that are otherwise not possible to code.
  • <xsl:sequence> can now take a sequence constructor just like other instructions.
  • <xsl:map> and <xsl:map-entry> have been introduced to support declarative creation of maps, which is in turn a new datatype of XPath 3.1, but supported in XSLT 3.0 even if a processor does not specifically supports XPath 3.1.
  • Dynamic evaluation of XPath expressions is a feature that has been wished for since XSLT 1.0 and is supported through <xsl:evaluate>. For security reasons, this feature can be switched off.
  • With <xsl:assert> you can create assertions for test-based programming (TDD). Assertions are switched off by default but can be switched on during debugging.
  • The mandatory order in which <xsl:import> must appear as first declaration in the stylesheet has been lifted.
  • To specify what should be used as context item for global variables and parameters, <xsl:global-context-item> can be used at the root level.
  • To specify the type of node that a template expects, use <xsl:context-item>. This can also be used to prohibit a context item, for instance with named templates.

New or enhanced attributes

Summary of several attributes that have been added to existing elements, or have come available to all elements in XSLT 3.0:

  • All components (variables, parameters, attribute sets, functions, templates, modes) have a visibility="public|final|abstract|private" attribute to set whether or not the attribute can be used from a package (public, final) or not (private), whether it can be overridden (public) or not (abstract), or whether it is defined, but does not have an implementation yet (abstract).
  • static="yes|no" can be used to create static parameters that allow you to declare a variable or parameter to be used during the static compilation phase, a very powerful addition to the use-when XSLT 2.0 attribute for static inclusion or exclusion.
  • Calculated attributes also known as shadow attributes turn any XSLT attribute into a statically calculated attribute value template by simply prefixing it with an underscore, adding strong meta-programming capabilities to the language.
  • declared-modes="yes|no" can be used on the <xsl:package> root declaration to force declaration of modes, preventing typos with inadvertent usage of non-existing mode names. The default is "yes".
  • Boolean attributes are now simplified to take yes|true|1 for true and no|false|0 for false, which helps in particular with meta-programming with shadow attributes.
  • default-mode can be used to set the default mode on any element or literal result element.
  • <xsl:copy> now has a select attribute to change focus
  • function declarations can be cached with the new cache attribute
  • determinism of functions can be forced with new-each-time, which also serves as a hint to processors to do certain optimizations.
  • error-code sets the error to be raised with <xsl:message> and terminate="yes" or for <xsl:assert>, which can subsequently be caught with <xsl:try> and <xsl:catch>.
  • The select attribute on <xsl:value-of> is no longer mandatory, even when the sequence constructor is empty. This is done for orthogonality with other instructions. The effect is to create a zero-length text node.
  • Static expressions, like the ones used in shadow attributes, in use-when attributes or in static parameters, may reference external documents. In XSLT 2.0 this was prohibited. The set of available external documents is implementation dependent, but by default, any URI that can automatically be dereferenced to a local file or an online document is accessible.
  • HTML5 can be created by setting <xsl:output method="html" html-version="5">.
  • The item-separator attribute was added on <xsl:output. to support serializing by separating a sequence of items by something other than a space.
  • The attribute build-tree on <xsl:output> can be used to specify whether a (document) tree should be build as output, or a sequence. In the first case, the effect of item-separator is void.

New XLST 3.0 functions

Not to be confused with XPath 3.0, which introduces a large set of new functions, XSLT 3.0 only has a handful of new functions:

  • fn:xml-to-json and fn:json-to-xml convert XML to JSON and back.
  • fn:accumulator-before and fn:accumulator-after get the pre-traverse and post-traverse value of an accumulator.
  • fn:copy-of is the functional equivalent of <xsl:copy-of>.
  • fn:snapshot is similar to fn:copy-of, except that it also copies all ancestors of the current node. In other words, it leaves the hierarchy intact, except that siblings, following and preceding nodes are not copied with.
  • For support of the new map type, from XPath 3.1 (formerly part of XSLT 3.0) the functions map:merge, map:contains, map:keys, map:get, map:size, map:put, map:entry, map:remove and map:for-each have been added.
  • Get the current output URI (the URI used in <xsl:result-document>, or the principal output URI, if any) with fn:current-output-uri.
  • fn:element-available is simplified and works with any element defined in the XSLT namespace.
  • fn:available-system-properties was a late addition to the specification and returns a list of all available system properties known by the processor. Typically this will be the default list of system properties, but processors may support more and this function is meant to find out which these are.
  • fn:system-property has been made more useful by adding the following properties:
    • xsl:version returns 3.0 for XSLT 3.0 processors.
    • xsl:vendor returns "Exselt" in case of Exselt.
    • xsl:vendor-url returns "http://exselt.net" for Exselt.
    • xsl:product-name returns "Exselt" for the Exselt processor.
    • xsl:product-version returns the version of the Exselt processor.
    • xsl:is-schema-aware should return true if the schema-aware feature is supported. This is still in development, as a result, presently returns false for Exselt.
    • xsl:supports-serialization returns true for Exselt, meaning it supports serializing the result tree. You can use this in conjunction with <xsl:result-document>.
    • xsl:supports-backwards-compatibility returns true for Exselt, even though some corner cases are not supported and disable-output-escaping is not supported (though that is not a requirement, we realize that many XSLT 1.0 and even 2.0 stylesheets may still use this feature, even though it has been deprecated for over a decade).
    • xsl:supports-namespace-axis returns true for Exselt, meaning that we support the namespace axis natively.
    • xsl:supports-streaming returns true for Exselt, meaning that we claim to support streaming (that is, processing large documents by using special limiting rules on language constructs and XPath usage), even though the specification has changed a lot since its last inception and we have not yet caught up with the implementation (as of July 2015). We are, however, pretty close with the guaranteed-streamability analysis report, while not a requirement per se, can come in handy when trying to make your stylesheet streamable. You can get such a report by specifying -sa on the command-line.
    • xsl:supports-dynamic-evaluation returns true, unless you have disabled this manually. Likewise, element-available('xsl:evaluate') will return true, unless it is disabled. For compiled packages, you can currently not disable this dynamically, so you need to compile your package with, or without evaluation support. A compiled package can still check at runtime whether the using package has dynamic evaluation switched off, which can be found by using these calls dynamically, as opposed to statically.
    • xsl:xpath-version returns 3.0 for Exselt. With XSLT 3.0, processors must support XPath 3.0, but may support XPath 3.1. If they only support XPath 3.0, they must still support maps, the map functions and the lookup syntax with $map?keyname. We support all of this, except the lookup syntax. XPath 3.1 is planned, with as main new feature the addition of arrays.
    • xsl:xsd-version will return 1.0 for Exselt. While we support the XSD 1.1 xs:error type and other additions to the atomic types, we currently have no plans to fully support XSD 1.1 in the near future, with our focus on conformance, streaming, concurrency and schema-aware processing (if you require XSD 1.1 support, drop us a note and we'll see what we can do in terms of release planning).

Other enhancements

Other improvements and additions to the XSLT 3.0 language not mentioned above include:

  • Stylesheets can now have the equivalent of int main() in other languages. A named template with the name xsl:initial-template is the default entry point for your stylesheet.
  • A function can be taken as entry-point to the stylesheet.
  • Any sequence of any type can be the input for the transformation, not just a document. As such it can be a sequence of documents, an empty sequence, a sequence of strings, or a sequence of parentless elements. A processor may distinguish between the initial match selection and the global context item, which is the input for global variables.
  • Support for text value templates, which work the same way as attribute value templates (and attribute within curly braces, as with test="{true()}") by adding expand-text="yes" to an outer element. This allows for much simplified sequence constructors and less use of <xsl:value-of> and <xsl:text> cluttering your code.
  • Patterns now support any kind of item, not just nodes, which allows you to match integers, strings, function items, maps, arrays. The pattern language is enhanced with predicate patterns, which is a pattern in the format of .[your predicate]. For instance, .[. instance of xs:string] will match any value item of type string.
  • The set of available functions in static expressions has been expanded to include all functions from XPath without limitation. However, functions defined in the XSLT standard are still inaccessible.
  • Composite keys are supported for <xsl:key>.
  • Regular expressions now accept zero-length string matches and repeats: fn:matches(foo, "(\d{4})|^$") matches an empty line or a line with four digits. Likewise, <xsl:analyze-string select="description" regex=".*"> will match each whole line in the input, whether it is an empty line or a non-empty line. Such expressions were not allowed prior to XSLT 3.0.
  • Recoverable dynamic errors and their implementation-defined recovery actions have been dropped. Most have now pre-defined recovery actions, others are now always a (catchable) error.