View Old View New View Both View Only Previous Next

This draft contains only sections that have differences from the version that it modified.

W3C

XSL Transformations (XSLT) Version 4.0

W3C Editor's Draft 23 February 2026

This version:
https://qt4cg.org/specifications/xslt-40/
Latest version:
https://qt4cg.org/specifications/xslt-40/
Most recent Recommendation of XSL Transformations (XSLT):
https://www.w3.org/TR/xslt-30/
Editor:
Michael Kay, Saxonica <http://www.saxonica.com/>

The following associated resources are available: Specification in XML format, XSD 1.1 Schema for XSLT 4.0 Stylesheets (non-normative), Relax-NG Schema for XSLT 4.0 Stylesheets (non-normative), Stylesheet for XML-to-JSON conversion (non-normative)


Abstract

This specification defines the syntax and semantics of XSLT 4.0, a language designed primarily for transforming XML documents into other XML documents.

XSLT 4.0 is a revised version of the XSLT 3.0 Recommendation [XSLT 3.0] published on 8 June 2017. Changes are presented in 1.2 What’s New in XSLT 4.0?.

XSLT 4.0 is designed to be used in conjunction with XPath 4.0, which is defined in [XPath 4.0]. XSLT shares the same data model as XPath 4.0, which is defined in [XDM 3.0], and it uses the library of functions and operators defined in [Functions and Operators 4.0]. XPath 4.0 and the underlying function library introduce a number of enhancements, for example the availability of union and record types.

This document contains hyperlinks to specific sections or definitions within other documents in this family of specifications. These links are indicated visually by a superscript identifying the target specification: for example XP for XPath 4.0, DM for the XDM data model version 4.0, FO for Functions and Operators version 4.0.

Status of this Document

This section describes the status of this document at the time of its publication. Other documents may supersede this document. A list of current W3C publications and the latest revision of this technical report can be found in the W3C technical reports index at https://www.w3.org/TR/.

This document has no official standing. It is produced by the editor as a proposal for community review. Insofar as it copies large amounts of text from the W3C XSLT 3.0 Recommendation, W3C copyright and similar provisions apply.

Dedication

The publications of this community group are dedicated to our co-chair, Michael Sperberg-McQueen (1954–2024).


19 Streamability

This section contains rules that can be used to determine properties of constructs in the stylesheet — specifically, the posture and sweep of a construct — which enable the streamability of the stylesheet to be assessed.

These properties are used to determine the streamability of:

In each case, the conditions for constructs to be guaranteed-streamable are defined in terms of these properties. The result of this analysis in turn (see 19.10 Streamability Guarantees) imposes rules on how the constructs are handled by processors that implement the streaming feature. The analysis has no effect on the behavior of processors that do not implement this feature.

The analysis is relevant to constructs such as streamable template rules and the xsl:source-document instruction that process a single streamed input document. The xsl:merge instruction, which processes multiple streamed inputs, has its own rules.

The rules in this section operate on the expression tree (more properly, construct tree) that is typically output by the XSLT and XPath parser. For the most part, the rules depend only on identifying the syntactic constructs that are present.

The rules in this section generally consider each component in the stylesheet (and in the case of template rules, each template rule) in isolation. The exception is that where a component contains references to other components (such as global variables, functions, or named templates), then information from the signature of the referenced component is sometimes used. This is invariably information that cannot be changed if a component is overridden in a different package. The analysis thus requires as a pre-condition that function calls and calls on named templates have been resolved to the extent that the corresponding function/template signature is known.

The detailed way in which the construct tree is derived from the lexical form of the stylesheet is not described in this specification. There are many ways in which the tree can be optimized without affecting the result of the rules in this section: for example, a sequence constructor containing a single instruction can be replaced by that instruction, and a parenthesized expression can be replaced by its content.

[Definition: The term construct refers to the union of the following: a sequence constructor, an instruction, an attribute set, a value template, an expression, or a pattern.]

These constructs are classified into construct kinds: in particular, instructions are classified according to the name of the XSLT instruction, and expressions are classified according to the most specific production in the XPath grammar that the expression satisfies. (This means, for example, that 2+2 is classified as an AdditiveExpr, rather than say as a UnionExpr; although it also satisfies the production rule for UnionExpr, AdditiveExpr is more specific.)

[Definition: For every construct kind, there is a set of zero or more operand roles.] For example, an AdditiveExpr has two operand roles, referred to as the left-hand operand and the right-hand operand, while an IfExpr has three, referred to as the condition, the then-clause, and the else-clause. A function call with three arguments has three operand roles, called the first, second, and third arguments. The names of the operand roles for each construct kind are not formally listed, but should be clear from the context.

[Definition: In an actual instance of a construct, there will be a number of operands. Each operand is itself a construct; the construct tree can be defined as the transitive relation between constructs and their operands.] Each operand is associated with exactly one of the operand roles for the construct type. There may be operand roles where the operand is optional (for example, the separator attribute of the xsl:value-of instruction), and there may be operand roles that can be occupied by multiple operands (for example, the xsl:when/@test condition in xsl:choose, or the arguments of the concat function).

Operand roles have a number of properties used in the analysis:

Note:

There is one known case where this definition makes an operand higher-order even though it is only evaluated once: specifically, the sequence constructor contained in the body of an xsl:copy instruction that has a select attribute. See 19.8.4.12 Streamability of xsl:copy for further details.

[Definition: For some construct kinds, one or more operand roles may be defined to form a choice operand group. This concept is used where it is known that operands are mutually exclusive (for example the then and else clauses in a conditional expression).]

[Definition: The combined posture of a choice operand group is determined by the postures of the operands in the group (the operand postures), and is the first of the following that applies:

  1. If any of the operand postures is roaming, then the combined posture is roaming.

  2. If all of the operand postures are grounded, then the combined posture is grounded.

  3. If one or more of the operand postures is climbing and the remainder (if any) are grounded, then the combined posture is climbing.

  4. If one or more of the operand postures is striding and the remainder (if any) are grounded, then the combined posture is striding.

  5. If one or more of the operand postures is crawling and each of the remainder (if any) is either striding or grounded, then the combined posture is crawling.

  6. Otherwise (for example, if the group includes both an operand with climbing posture and one with crawling posture), the combined posture is roaming.

]

[Definition: The type-determined usage of an operand is as follows: if the required type (ignoring occurrence indicator) is fn(*) or a subtype thereof, then inspection; if the required type (ignoring occurrence indicator) is an atomic or union type, then absorption; otherwise navigation.]

[Definition: The type-adjusted posture and sweep of a construct C, with respect to a type T, are the posture and sweep established by applying the general streamability rules to a construct D whose single operand is the construct C, where the operand usage of C in D is the type-determined usage based on the required type T.]

Note:

In effect, the type-adjusted posture and sweep are the posture and sweep of the implicit expression formed to apply the coercion rules to the argument of a function or template call, or to the result of a function or template, given knowledge of the required type. For example, an expression such as discount in the function call abs(discount), which would otherwise be striding and consuming, becomes grounded and consuming because of the implicit atomization triggered by the coercion rules.

The process of determining whether a construct is streamable reduces to determining properties of the constructs in the construct tree. The properties in question (which are described in greater detail in subsequent sections) are:

  1. The static type of the construct. When the construct is evaluated, its value will always be an instance of this type. The value is a U-type; although type inferencing is capable of determining information about the cardinality as well as the item type, the streamability analysis makes no use of this.

  2. The context item type: that is, the static type of the context item potentially used as input to the construct. When the construct is evaluated, the context item used to evaluate the construct (if it is used at all) will be an instance of this type.

  3. [Definition: The posture of the expression. This captures information about the way in which the streamed input document is positioned on return from evaluating the construct. The posture takes one of the values climbing, striding, crawling, roaming, or grounded.] The meanings of these terms are explained in 19.4 Determining the Posture of a Construct.

  4. [Definition: The context posture. This captures information about how the context item used as input to the construct is positioned relative to the streamed input. The context posture of a construct C is the posture of the expression whose value sets the focus for the evaluation of C.] Rules for determining the context posture of any construct are given in 19.5 Determining the Context Posture.

  5. The sweep of the construct. The sweep of a construct gives information about whether and how the evaluation of the construct changes the current position in a streamed input document. The possible values are motionless, consuming, and free-ranging. These terms are explained in 19.6 The Sweep of a Construct.

The values of these properties for a top-level construct such as the body of a template rule determine whether the construct is streamable.

The values of these properties are not independent. For example, if the static type is atomic, then the posture will always be grounded; if the sweep is free-ranging, then the posture will always be roaming.

The posture and sweep of a construct, as defined above, are calculated in relation to a particular streamed input document. If there is more than one streamed input document, then a construct that is motionless with respect to one streamed input might be consuming with respect to another. In practice, though, the streamability analysis is only ever concerned with one particular streamed input at a time; constructs are analyzed in relation to the innermost containing xsl:template, xsl:source-document, xsl:accumulator, or xsl:merge-source element, and this container implicitly defines the streamed input document that is relevant. The streamed input document affecting a construct is always the document that contains the context item for evaluation of that construct.

19.8 Classifying Constructs

This section defines the properties of every kind of construct that may appear in a stylesheet. It identifies the operand roles and their usage, and it gives the rules that define the posture and sweep of the construct. In cases where the general streamability rules apply, there is still an entry for the construct in order to define its operands and their usages, since this information is needed by the general rules.

The following sections describe this categorization for each kind of construct:

19.8.4 Classifying Instructions

This section describes how instructions are classified with respect to their streamability. The criteria are given first for literal result elements and extension instructions, then for each XSLT instruction, listed alphabetically.

19.8.4.23 Streamability of xsl:map

Changes in 4.0  

  1. The special rule allowing xsl:map to have multiple consumable operands does not apply if duplicate keys are permitted.  [Issue 2036 ]

The posture and sweep of the xsl:map instruction are determined by the first of the following that applies:

  1. If the sequence constructor within the instruction consists exclusively of xsl:map-entry instructions (and xsl:fallback instructions, which are ignored), and the duplicates attribute is absent, then:

    1. If any of these xsl:map-entry children is roaming or free-ranging, then roaming and free-ranging;

    2. Otherwise, grounded and the widest sweep of the xsl:map-entry children.

  2. Otherwise, the posture and sweep of the xsl:map instruction are the posture and sweep of the contained sequence constructor.

Note:

See discussion in 21.2 Maps and Streaming.

The effect of the rules is that it is possible to compute multiple map entries in a single pass of the streamed input document. For example, the following is streamable:

<xsl:map>
  <xsl:map-entry key="'authors'" select="copy-of(author)"/>
  <xsl:map-entry key="'editors'" select="copy-of(editor)"/>
</xsl:map>

The call on copy-of is necessary to ensure that the content of the map entry is grounded; it is not possible to create a map whose entries contain references to streamed nodes.

This rule does not apply when duplicate keys are permitted, because in that situation the child xsl:map-entry instructions generally need to be evaluated in the order they are written, rather than in the order their operands are encountered.

I Changes since XSLT 3.0 (Non-Normative)

I.1 Changes in this specification

  1. Use the arrows to browse significant changes since the 3.0 version of this specification.

    See 1.2 What’s New in XSLT 4.0?

  2. Sections with significant changes are marked Δ in the table of contents.

    See 1.2 What’s New in XSLT 4.0?

  3. Named item types can be declared using the new xsl:item-type element. This is designed to avoid repeating lengthy type definitions (for example function types) every time they are used. [This feature was present in the editor's draft presented to the WG when it started work.]

    See 5.5.1 Named Item Types

  4. The xsl:for-each and xsl:apply-templates instructions acquire an attribute separator that can be used to insert content between adjacent items. [This change was in the editor's draft adopted as a baseline when the WG commenced work.]

    See 6.3 Applying Template Rules

  5. PR 751 1386 

    The result type of a mode can be declared using an as attribute. The result type of all template rules in this mode must be consistent with this, as must the values returned by any built-in template rules for the mode.

    See 6.7.5 Declaring the Result Type of a Mode

  6. The xsl:for-each and xsl:apply-templates instructions acquire an attribute separator that can be used to insert content between adjacent items. [This change was in the editor's draft adopted as a baseline when the WG commenced work.]

    See 7.1 The xsl:for-each instruction

  7. Numeric values of type xs:decimal are compared as decimals, without first converting to xs:double.

    See 13.1.2 Comparing Sort Key Values

  8. Functions that accept a lexical QName as an argument, such as key, function-available, element-available, type-available, system-property, accumulator-before, and accumulator-after, now have the option of supplying an xs:QName value instead. [This change was in the editor's draft accepted by the WG as its baseline when it started work.]

    See 20 Additional Functions

  9. Functions that accept a lexical QName as an argument, such as key, function-available, element-available, type-available, system-property, accumulator-before, and accumulator-after, now have the option of supplying an xs:QName value instead. [This change was in the editor's draft accepted by the WG as its baseline when it started work.]

    See 24 Extensibility and Fallback

  10. It is possible to invoke a named template using an extension instruction, specifically, an element whose name matches the name of the named template.

    See 10.1.3 Invoking Named Templates using Extension Instructions

    See 24.2 Extension Instructions

  11. A new attribute xsl:map/@duplicates is available, allowing control over how duplicate keys are handled by the xsl:map instruction.

    See 21.1.2 Handling of duplicate keys

  12. The semantics of patterns using the intersect and except operators have been changed to reflect the intuitive meaning: for example a node now matches A except B if it matches A and does not match B.

    See 5.4.2.3 Node Patterns

  13. A new attribute xsl:for-each-group/@split-when is available to give applications more complete control over how a sequence is partitioned

    See 14 Grouping

  14. Duplicate xsl:include declarations within a stylesheet level are now ignored, preventing spurious errors caused by the presence of duplicate named components.

    See 3.11.2 Stylesheet Inclusion

  15. Named record types are introduced.

    See 5.5.2 Named Record Types

  16. The contents of a character map declared using xsl:character-map are now available dynamically via a new character-map function.

    See 26.4 The character-map function

  17. New variables err:stack-trace, err:additional, and err:map are available within an xsl:catch clause.

    See 8.4 Try/Catch

  18. The input to the serializer can be defined using the select attribute of xsl:result-document as an alternative to using a sequence constructor.

    See 25.1 Creating Secondary Results

  19. It is no longer an intrinsic error for a global variable to refer to itself; this is now permitted, for example in cases where the value of the global variable is a recursive inline function. Cases where self-reference would not make sense are covered by the existing rules on circularities: see 9.11 Circular Definitions.

    See 9.5 Global Variables and Parameters

  20. The default value for the indent parameter is now defined to be no for all output methods other than html and xhtml.

    See 26.2 Serialization parameters

  21. The xsl:map instruction allows a select attribute as an alternative to the contained sequence constructor.

    See 21.1 Map Instructions

    The xsl:map-entry instruction, in common with other instructions, now raises error XTSE3185 (rather than XTSE3280) if both a select attribute and a sequence constructor are present.

    See 21.1 Map Instructions

  22. Composite sort keys are allowed in xsl:sort.

    See 13.1.2 Comparing Sort Key Values

  23. The xsl:mode declaration acquires an attribute copy-namespaces which determines whether or not the built-in template rule copies unused namespace bindings.

    See 6.7.1 Declaring Modes

  24. The default priority for a template rule using a union pattern has changed. This change may cause incompatible behavior.

    See 6.6 Default Priority for Template Rules

  25. The xsl:apply-imports and xsl:next-match instructions automatically pass supplied parameters to the overridden template rule.

    See 6.9 Overriding Template Rules

  26. The xsl:select instruction is new in 4.0.

    See 11.11 The xsl:select Instruction

  27. The special rule allowing xsl:map to have multiple consumable operands does not apply if duplicate keys are permitted.

    See 19.8.4.23 Streamability of xsl:map

  28. PR 159 

    Parameters on functions declared using xsl:function can now be defined as optional, with a default value supplied.

    See 9.2.2 Default Values of Parameters

    See 10.3 Stylesheet Functions

  29. PR 237 

    The xsl:if instruction now allows then and else attributes.

    See 8.1 Conditional Processing with xsl:if

    In xsl:choose, the xsl:when and xsl:otherwise elements can take a select attribute in place of a sequence constructor.

    See 8.2 Conditional Processing with xsl:choose

    A new xsl:switch instruction is introduced.

    See 8.3 Conditional Processing with xsl:switch

  30. PR 326 

    The higher-order-function feature no longer exists; higher-order functions are now a core part of XSLT, no longer an optional extra.

    See 27 Conformance

  31. PR 353 

    A new attribute, main-module, is added to the xsl:stylesheet element. The attribute is provided for the benefit of development tools such as syntax-directed editors to provide information about all the components (variables, functions, etc) visible within a stylesheet module.

    See 3.7 Stylesheet Element

    A new element xsl:note is available for documentation and similar purposes: it can appear anywhere in the stylesheet and is ignored by the XSLT processor.

    See 3.13.2 The xsl:note element

  32. PR 401 

    Patterns (especially those used in template rules) can now be defined by reference to item types, so any item type can be used as a match pattern. For example match="record(longitude, latitude, *)" matches any map that includes the key values "longitude" and "latitude".

    See 5.4.2.2 Type Patterns

  33. PR 406 

    The new instruction xsl:array is introduced to allow construction of arrays.

    See 22.1 Array Construction

  34. PR 470 

    The xsl:stylesheet, xsl:transform, or xsl:package element may have a fixed-namespaces attribute making it easier to have the same namespace declarations in force throughout a stylesheet.

    See 3.7.1 The fixed-namespaces Attribute

  35. PR 489 

    The xsl:matching-substring and xsl:non-matching-substring elements within xsl:analyze-string may now take a select attribute in place of a contained sequence constructor.

    See 17.1 The xsl:analyze-string Instruction

  36. PR 534 

    A new serialization parameter escape-solidus is provided to control whether the character / is escaped as \/ by the JSON serialization method.

    See 25.1 Creating Secondary Results

    See 26.1 The xsl:output declaration

  37. PR 542 

    A mode (called an enclosing mode) can be defined in which all the relevant template rules are children of the xsl:mode element. This is intended to allow a stylesheet design in which it is easier to determine which rules might apply to a given xsl:apply-templates call.

    See 6.7.6 Enclosing Modes

  38. PR 599 

    Simplified stylesheets no longer require an xsl:version attribute (which means they might not need a declaration of the XSLT namespace). Unless otherwise specified, a 4.0 simplified stylesheet defaults expand-text to true.

    See 3.8 Simplified Stylesheet Modules

  39. PR 635 

    The rules concerning the compatibility of schemas imported by different packages have been clarified. It is now explicitly stated that instructions that trigger validation must use the imported schema of the package in which validation is invoked. This differs from the current practice of some XSLT 3.0 processors, which may use (for example) a schema formed from the union of the imported schemas in all packages.

    See 3.15 Importing Schema Components

    See 25.4 Validation

  40. PR 717 

    Capturing accumulators have been added; when streaming with a capturing accumulator, the accumulator-after has full access to a snapshot of the matched element node.

    See 18.2.9 Capturing Accumulators

  41. PR 718 

    To allow recursive-descent transformation on a tree of maps and arrays, a new set of built-in templates rules shallow-copy-all is introduced.

    See 6.8 Built-in Template Rules

  42. PR 751 

    The xsl:mode declaration acquires an attribute as="sequence-type" which declares the return type of all template rules in that mode.

    See 6.7.1 Declaring Modes

  43. PR 1181 

    The [xsl:]xpath-default-namespace attribute can be set to the value ##any, which causes unprefixed element names to match in any namespace or none.

    See 5.1.2 Unprefixed Lexical QNames in Expressions and Patterns

  44. PR 1250 

    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.

    See 5.6 Defining a Decimal Format

  45. PR 1254 

    The rules concerning the interpretation of xsi:schemaLocation and xsi:noNamespaceSchemaLocation attributes have been tightened up.

    See 25.4 Validation

    See 25.4 Validation

  46. PR 1306 

    An as attribute is available on the xsl:sequence instruction.

    See 11.10 The xsl:sequence Instruction

  47. PR 1361 

    The term atomic value has been replaced by atomic item.

    See 2.1 Terminology

  48. PR 1378 

    A function call at the outermost level can now be named using any valid EQName (for example fn:doc) provided it binds to one of the permitted functions fn:doc, fn:id, fn:element-with-id, fn:key, or fn:root. If two functions are called, for example doc('a.xml')/id('abc'), it is no longer necessary to put the second call in parentheses.

    See 5.4.2.3 Node Patterns

  49. PR 1442 

    Default priorities are added for new forms of ElementTest and AttributeTest, for example element(p:*) and element(a|b).

    See 6.6 Default Priority for Template Rules

  50. PR 1622 

    The rules for equality comparison have changed to bring keys into line with maps.

    See 20.2.2 fn:key

    New in 4.0.

    See 20.2.3 fn:map-for-key

  51. PR 1689 

    Composite merge keys are now allowed.

    See 15 Merging

  52. PR 1703 

    Ordered maps are introduced.

    See 21.1 Map Instructions

  53. PR 1819 

    Different parts of a stylesheet may now use different imported schemas.

    See 2.10 Stylesheets and XML Schemas

    The standard attribute [xsl:]schema-role is introduced, to allow different parts of a stylesheet to use different schemas.

    See 3.4 Standard Attributes

    Different parts of a stylesheet may now use different imported schemas.

    See 3.15 Importing Schema Components

    A stylesheet can import multiple schemas with different schema role names.

    See 3.15.1 Multiple Schemas

  54. PR 1856 

    The rules have been adjusted to allow for new capabilities in regular expressions, such as zero-width assertions.

    See 17.1 The xsl:analyze-string Instruction

  55. PR 1858 

    The xsl:record instruction is introduced to make construction of record maps simpler.

    See 21.1.1 Record Instruction

    Attribute xsl:record/@xsl:duplicates is added to control duplicate keys handling in the xsl:record instruction.

    See 21.1.2 Handling of duplicate keys

  56. PR 2006 

    A new function fn:apply-templates is introduced.

    See 6.7.3 The apply-templates Function

  57. PR 2015 

    A variable-binding with no as or select attribute no longer attempts to create an implicit document node if the sequence constructor contains an xsl:map, xsl:array, or xsl:select child instruction.

    See 9.3 Values of Variables and Parameters

  58. PR 2030 

    In order to reduce duplication between the XSLT and XQuery specifications, description of the validation process has been moved to the Functions and Operators specification.

    See 25.4 Validation