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


2 Concepts

2.5 Rule-Based Processing

The classic method of executing an XSLT transformation is to apply template rules to the root node of an input document (see 2.3.3 Apply-Templates Invocation). The operation of applying templates to a node searches the stylesheet for the best matching template rule for that node. This template rule is then evaluated. A common coding pattern, especially when XSLT is used to convert XML documents into display formats such as HTML, is to have one template rule for each kind of element in the source document, and for that template rule to generate some appropriate markup elements, and to apply templates recursively to its own children. The effect is to perform a recursive traversal of the source tree, in which each node is processed using the best-fit template rule for that node. The final result of the transformation is then the tree produced by this recursive process. This result can then be optionally serialized (see 2.3.6 Post-processing the Raw Result).

Example: Example of Rule-Based Processing

This example uses rule-based processing to convert a simple XML input document into an HTML output document.

The input document takes the form:

<PERSONAE PLAY="OTHELLO">
    <TITLE>Dramatis Personae</TITLE>
    <PERSONA>DUKE OF VENICE</PERSONA>
    <PERSONA>BRABANTIO, a senator.</PERSONA>
    <PERSONA>Other Senators.</PERSONA>
    <PERSONA>GRATIANO, brother to Brabantio.</PERSONA>
    <PERSONA>LODOVICO, kinsman to Brabantio.</PERSONA>
    <PERSONA>OTHELLO, a noble Moor in the service of the Venetian state.</PERSONA>
    <PERSONA>CASSIO, his lieutenant.</PERSONA>
    <PERSONA>IAGO, his ancient.</PERSONA>
    <PERSONA>RODERIGO, a Venetian gentleman.</PERSONA>
    <PERSONA>MONTANO, Othello's predecessor in the government of Cyprus.</PERSONA>
    <PERSONA>Clown, servant to Othello. </PERSONA>
    <PERSONA>DESDEMONA, daughter to Brabantio and wife to Othello.</PERSONA>
    <PERSONA>EMILIA, wife to Iago.</PERSONA>
    <PERSONA>BIANCA, mistress to Cassio.</PERSONA>
    <PERSONA>Sailor, Messenger, Herald, Officers, 
             Gentlemen, Musicians, and Attendants.</PERSONA>
  </PERSONAE>

The stylesheet to render this as HTML can be written as a set of template rules:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="3.0"
    expand-text="yes">
    
 <xsl:strip-space elements="PERSONAE"/>   
    
 <xsl:template match="PERSONAE">
   <html>
     <head>
       <title>The Cast of {@PLAY}</title>
     </head>
     <body>
       <xsl:apply-templates/>
     </body>
   </html>
 </xsl:template>
 
 <xsl:template match="TITLE">
   <h1>{.}</h1>
 </xsl:template>
 
 <xsl:template match="PERSONA[count(tokenize(., ',')) = 2]">
   <p><b>{substring-before(., ',')}</b>: {substring-after(., ',')}</p>
 </xsl:template> 

 <xsl:template match="PERSONA">
   <p><b>{.}</b></p>
 </xsl:template>

</xsl:stylesheet>

There are four template rules here:

  • The first rule matches the outermost element, named PERSONAE (it could equally have used match="/" to match the document node). The effect of this rule is to create the skeleton of the output HTML page. Technically, the body of the template is a sequence constructor comprising a single literal result element (the html element); this in turn contains a sequence constructor comprising two literal result elements (the head and body elements). The head element is populated with a literal title element whose content is computed as a mixture of fixed and variable text using a text value template. The body element is populated by evaluating an xsl:apply-templates instruction.

    The effect of the xsl:apply-templates instruction is to process the children of the PERSONAE element in the source tree: that is, the TITLE and PERSONA elements. (It would also process any whitespace text node children, but these have been stripped by virtue of the xsl:strip-space declaration.) Each of these child elements is processed by the best matching template rule for that element, which will be one of the other three rules in the stylesheet.

  • The template rule for the TITLE element outputs an h1 element to the HTML result document, and populates this with the value of ., the context item. That is, it copies the text content of the TITLE element to the output h1 element.

  • The last two rules match PERSONA elements. The first rule matches PERSONA elements whose text content contains exactly one comma; the second rule matches all PERSONA elements, but it has lower priority than the first rule (see 6.66.5 Default Priority for Template Rules), so in practice it applies only to PERSONA elements that contain no comma or multiple commas.

    For both rules the body of the rule is a sequence constructor containing a single literal result element, the p element. These literal result elements contain further sequence constructors comprising literal result elements and text nodes. In each of these examples the text nodes are in the form of a text value template: in general this is a combination of fixed text together with XPath expressions enclosed in curly braces, which are evaluated to form the content of the containing literal result element.

[Definition: A stylesheet contains a set of template rules (see 6 Template Rules). A template rule has three parts: a pattern that is matched against selected items (often but not necessarily nodes), a (possibly empty) set of template parameters, and a sequence constructor that is evaluated to produce a sequence of items.] In many cases these items are newly constructed nodes, which are then written to a result tree.

3 Stylesheet Structure

This section describes the overall structure of a stylesheet as a collection of XML documents.

3.5 Packages

[Definition: An explicit package is represented by an xsl:package element, which will generally be the outermost element of an XML document. When the xsl:package element is not used explicitly, the entire stylesheet comprises a single implicit package.] (This specification does not preclude the xsl:package being embedded in another XML document, but it will never have any other XSLT element as an ancestor).

<xsl:package
  id? = id
  name? = uri
  package-version? = string〔'1'〕
  version = decimal
  input-type-annotations? = "preserve" | "strip" | "unspecified"〔'unspecified'〕
  declared-modes? = boolean〔'yes'〕
  default-mode? = eqname | "#unnamed"〔'#unnamed'〕
  default-validation? = "preserve" | "strip"〔'strip'〕
  default-collation? = uris
  extension-element-prefixes? = prefixes
  exclude-result-prefixes? = prefixes
  expand-text? = boolean〔'no'〕
  fixed-namespaces? = string
  schema-role? = ncname
  use-when? = expression〔true()〕
  xpath-default-namespace? = uri >
  <!-- Content: ((xsl:expose | declarations)*) -->
</xsl:package>

[Definition: The content of the xsl:package element is referred to as the package manifest].

The version attribute indicates the version of the XSLT language specification to which the package manifest conforms. The value should normally be 4.0. If the value is numerically less than 4.0, the content of the xsl:package element is processed using the rules for backwards compatible behavior (see 3.9 Backwards Compatible Processing). If the value is numerically greater than 4.0, it is processed using the rules for forwards compatible behavior (see 3.10 Forwards Compatible Processing).

A package typically has a name, given in its name attribute, which must be an absolute URI. Unnamed packages are allowed, but they can only be used as the “top level” of an application; they cannot be the target of an xsl:use-package declaration in another package.

A package may have a version identifier, given in its package-version attribute. This is used to distinguish different versions of a package. The value of the version attribute, after trimming leading and trailing whitespace, must conform to the syntax given in 3.5.1 Versions of a Package. If no version number is specified for a package, version 1 is assumed.

The attributes default-collation, default-mode, default-validation, exclude-result-prefixes, expand-text, extension-element-prefixes, use-when, version, and xpath-default-namespace are standard attributes that can appear on any XSLT element, and potentially affect all descendant elements. Their meaning is described in 3.4 Standard Attributes.

The package manifest contains the following elements, arbitrarily ordered:

  1. Zero or more xsl:expose declarations that define the interface offered by this package to the outside world. An xsl:expose declaration may appear only as a child of xsl:package.

  2. Zero or more additional declarations. These are the same as the declarations permitted as children of xsl:stylesheet or xsl:transform.

    Some declarations of particular relevance to packages include:

    1. The xsl:use-package declaration, which declares the names and versions of the packages on which this package depends.

    2. The optional xsl:global-context-item element; if present this element defines constraints on the existence and type of the global context item.

    3. Zero or more xsl:include and xsl:import declarations, which define additional stylesheet modules to be incorporated into this package.

    4. Zero or more ordinary declarations, that is, elements that are permitted as children of xsl:stylesheet or xsl:transform. One possible coding style is to include in the package manifest just a single xsl:import or xsl:include declaration as a reference to the effective top-level stylesheet module; this approach is particularly suitable when writing code that is required to run under releases of XSLT earlier than 3.0. Another approach is to include the substance of the top-level stylesheet module inline within the package manifest.

Example: An example package

The following example shows a package that offers a number of functions for manipulating complex numbers. A complex number is represented as a map with two entries, the keys being 0 for the real part, and 1 for the imaginary part.

<xsl:package
  name="http://example.org/complex-arithmetic.xsl"
  package-version="1.0"
  version="3.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  xmlns:f="http://example.org/complex-arithmetic.xsl">
  
  <xsl:function name="f:complex-number" 
                as="map(xs:integer, xs:double)" visibility="public">
    <xsl:param name="real" as="xs:double"/>
    <xsl:param name="imaginary" as="xs:double"/>
    <xsl:sequence select="{ 0: $real, 1: $imaginary }"/>
  </xsl:function>
  
  <xsl:function name="f:real" 
                as="xs:double" visibility="public">
    <xsl:param name="complex" as="map(xs:integer, xs:double)"/>
    <xsl:sequence select="$complex(0)"/>
  </xsl:function>
  
  <xsl:function name="f:imag" 
                as="xs:double" visibility="public">
    <xsl:param name="complex" as="map(xs:integer, xs:double)"/>
    <xsl:sequence select="$complex(1)"/>
  </xsl:function>
  
  <xsl:function name="f:add" 
                as="map(xs:integer, xs:double)" visibility="public">
    <xsl:param name="x" as="map(xs:integer, xs:double)"/>
    <xsl:param name="y" as="map(xs:integer, xs:double)"/>
    <xsl:sequence select="
         f:complex-number(
           f:real($x) + f:real($y), 
           f:imag($x) + f:imag($y))"/>
  </xsl:function>
  
  <xsl:function name="f:multiply" 
                as="map(xs:integer, xs:double)" visibility="public">
    <xsl:param name="x" as="map(xs:integer, xs:double)"/>
    <xsl:param name="y" as="map(xs:integer, xs:double)"/>
    <xsl:sequence select="
         f:complex-number(
           f:real($x)*f:real($y) - f:imag($x)*f:imag($y),
           f:real($x)*f:imag($y) + f:imag($x)*f:real($y))"/>
  </xsl:function>
  
  <!-- etc. -->
  
</xsl:package>

A more complex package might include private or abstract functions as well as public functions; it might expose components other than functions (for example, templates or global variables), and it might contain xsl:use-package elements to allow it to call on the services of other packages.

Note:

In this example, the way in which complex numbers are represented is exposed to users of the package. It would be possible to hide the representation by declaring the types on public functions simply as item(); but this would be at the cost of type safety.

A package that does not itself expose any components may be written using a simplified syntax: the xsl:package element is omitted, and the xsl:stylesheet or xsl:transform element is now the outermost element of the stylesheet module. For compatibility reasons, all the named templates and modes declared in the package are made public. More formally, the principal stylesheet module of the top-level package may be expressed as an xsl:stylesheet or xsl:transform element, which is equivalent to the package represented by the output of the following transformation, preserving the base URI of the source:

<xsl:transform version="3.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:t="http://www.w3.org/1999/XSL/TransformAlias">
 
    <xsl:namespace-alias stylesheet-prefix="t" result-prefix="xsl"/>
    
    <xsl:template match="xsl:stylesheet|xsl:transform">
      <t:package declared-modes="no">
        <xsl:copy-of select="@*"/>
        <t:expose component="mode" names="*" visibility="public"/>
        <t:expose component="template" names="*" visibility="public"/>
        <xsl:copy-of select="node()"/>
      </t:package>
    </xsl:template>
 </xsl:transform>

The effect of the input-type-annotations attribute is defined in 4.3.1 Stripping Type Annotations from a Source Tree.

A more extensive example of a package, illustrating how components in a package can be overridden in a client package, is given in 3.5.7 Worked Example of a Library Package.

3.5.4 Overriding Template Rules from a Used Package

The rules in the previous section apply to named components including functions, named templates, global variables, and named attribute sets. The rules for modes, and the template rules appearing within a mode, are slightly different.

The unnamed mode is local to a package: in effect, each package has its own private unnamed mode, and the unnamed mode of one package does not interact with the unnamed mode of any other package. An xsl:apply-templates instruction with no mode attribute is treated as a symbolic reference to the default mode defined for that instruction (see 3.7.3 The default-mode Attribute), which in turn defaults to the unnamed mode. Because the unnamed mode always has private visibility, it cannot be overridden in another package.

A named mode may be declared in an xsl:mode declaration as being either public, private, or final. The values of the visibility attribute are interpreted as follows:

Visibility Values for Named Modes, and their Meaning
ValueMeaning
publicA using package may use xsl:apply-templates to invoke templates in this mode; it may also declare additional template rules in this mode, which are selected in preference to template rules in the used package. These may appear only as children of the xsl:override element within the xsl:use-package element.
privateA using package may neither reference the mode nor provide additional templates in this mode; the name of the mode is not even visible in the using package, so no such attempt is possible. The using package can use the same name for its own modes without risk of conflict.
finalA using package may use xsl:apply-templates to invoke templates in this mode, but it must not provide additional template rules in this mode.

As with other named components, an xsl:use-package declaration may contain an xsl:accept element to control the visibility of a mode acquired from the used package. The allowed values of its visibility attribute are public, private, and final.

The xsl:mode declaration itself must not be overridden. A using package must not contain an xsl:mode declaration whose name matches that of a public or finalxsl:mode component accepted from a used package.

The xsl:expose and xsl:accept elements may be used to reduce the visibility of a mode in a using package; the same rules apply in general, though some of the rules are not applicable because, for example, modes cannot be abstract.

It is not possible for a package to combine the template rules from two other packages into a single mode. When xsl:apply-templates is used without specifying a mode, the chosen template rules will always come from the same package; when it is used with a named mode, then they will come from the package where the mode is defined, or any package that uses that package and adds template rules to the mode. If two template rules defined in different packages match the same node, then the rule in the using package wins over any rule in the used package; this decision is made before taking other factors such as import precedence and priority into account.

A static error occurs if two modes with the same name are visible within a package, either because they are both declared within the package, or because one is declared within the package and the other is acquired from a used package, or because both are accepted from different used packages.

The rules for matching template rules by import precedence and priority operate as normal, with the addition that template rules declared within an xsl:use-package element have higher precedence than any template rule declared in the used package. More specifically, given an xsl:apply-templates instruction in package P, naming a mode M that is declared in a used package Q and is overridden in P, the search order for template rules is:

  1. Rules declared within P (specifically, xsl:template rules declared as children of an xsl:override element within the xsl:use-package element that references package Q). If there are multiple rules declared within P that match a selected node, they are resolved on the basis of their explicit or implicit priority, and if the priorities are equal, the last one in declaration order wins.

  2. Rules declared within Q, taking import precedence, priority, and declaration order into account in the usual way (see 6.56.4 Conflict Resolution for Template Rules).

  3. Built-in template rules (see 6.86.7 Built-in Template Rules) selected according to the on-no-match attribute of the xsl:mode declaration (in Q), or its default.

If the mode is overridden again in a package R that uses P, then this search order is extended by adding R at the start of the search list, and so on recursively.

Note:

If existing XSLT code has been written to use template rules in the unnamed mode, a convenient way to incorporate this code into a library package is to add a stub module that defines a new named public or final mode, in which there is a single template rule whose content is the single instruction <xsl:apply-templates select="."/>. This in effect redirects xsl:apply-templates instructions using the named mode to the rules defined in the unnamed mode.

3.5.4.1 Requiring Explicit Mode Declarations

In previous versions of XSLT, modes were implicitly declared by simply using a mode name in the mode attribute of xsl:template or xsl:apply-templates. XSLT 3.0 introduced the ability to declare a mode explicitly using an xsl:mode declaration (see 6.7.16.6.1 Declaring Modes).

By default, within a package that is defined using an explicit xsl:package element, all modes must be explicitly declared. In an implicit package, however (that is, one rooted at an xsl:stylesheet or xsl:transform element), modes can be implicitly declared as in previous XSLT versions.

The declared-modes attribute of xsl:package determines whether or not modes that are referenced within the package must be explicitly declared. If the value is yes (the default), then it is an error to use a mode name unless the package either contains an explicit xsl:mode declaration for that mode, or accepts the mode from a used package. If the value is no, then this is not an error.

This attribute affects all modules making up the package, it is not confined to declarations appearing as children of the xsl:package element.

[ERR XTSE3085] It is a static error, when the effective value of the declared-modes attribute of an xsl:package element is yes, if the package contains an explicit reference to an undeclared mode, or if it implicitly uses the unnamed mode and the unnamed mode is undeclared.

For the purposes of the above rule:

  1. A mode is declared if either of the following conditions is true:

    1. The package contains an xsl:mode declaration for that mode.

    2. The mode is a public or final mode accepted from a used package.

  2. The offending reference may be either an explicit mode name, or the token #unnamed treated as a reference to the unnamed mode, or a defaulted mode attribute, and it may occur in any of the following:

    1. The mode attribute of an xsl:template declaration

    2. The mode attribute of an xsl:apply-templates instruction

    3. An [xsl:]default-mode attribute.

  3. A package implicitly uses the unnamed mode if either of the following conditions is true:

    1. There is an xsl:apply-templates element with no mode attribute, and with no ancestor-or-self having an [xsl:]default-mode attribute.

    2. There is an xsl:template element with a match attribute and no mode attribute, and with no ancestor-or-self having an [xsl:]default-mode attribute.

3.7 Stylesheet Element

Changes in 4.0  

  1. 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.   [Issue 87 PR 353 19 April 2023]

<xsl:stylesheet
  id? = id
  version = decimal
  default-mode? = eqname | "#unnamed"〔'#unnamed'〕
  default-validation? = "preserve" | "strip"〔'strip'〕
  input-type-annotations? = "preserve" | "strip" | "unspecified"〔'unspecified'〕
  default-collation? = uris
  extension-element-prefixes? = prefixes
  exclude-result-prefixes? = prefixes
  expand-text? = boolean
  fixed-namespaces? = string
  main-module? = uri
  schema-role? = ncname
  use-when? = expression〔true()〕
  xpath-default-namespace? = uri >
  <!-- Content: (declarations) -->
</xsl:stylesheet>

<xsl:transform
  id? = id
  version = decimal
  default-mode? = eqname | "#unnamed"〔'#unnamed'〕
  default-validation? = "preserve" | "strip"〔'strip'〕
  input-type-annotations? = "preserve" | "strip" | "unspecified"〔'unspecified'〕
  default-collation? = uris
  extension-element-prefixes? = prefixes
  exclude-result-prefixes? = prefixes
  expand-text? = boolean〔'no'〕
  fixed-namespaces? = string
  main-module? = uri
  schema-role? = ncname
  use-when? = expression〔true()〕
  xpath-default-namespace? = uri >
  <!-- Content: (declarations) -->
</xsl:transform>

A stylesheet module is represented by an xsl:stylesheet element in an XML document. xsl:transform is allowed as a synonym for xsl:stylesheet; everything this specification says about the xsl:stylesheet element applies equally to xsl:transform.

The version attribute indicates the version of XSLT that the stylesheet module requires. The attribute is required.

[ERR XTSE0110] The value of the version attribute must be a number: specifically, it must be a valid instance of the type xs:decimal as defined in [XML Schema Part 2].

The version attribute is intended to indicate the version of the XSLT specification against which the stylesheet is written. In a stylesheet written to use XSLT 4.0, the value should normally be set to 4.0. If the value is numerically less than 4.0, the stylesheet is processed using the rules for backwards compatible behavior (see 3.9 Backwards Compatible Processing). If the value is numerically greater than 4.0, the stylesheet is processed using the rules for forwards compatible behavior (see 3.10 Forwards Compatible Processing).

The effect of the input-type-annotations attribute is described in 4.3.1 Stripping Type Annotations from a Source Tree.

The [xsl:]default-validation attribute defines the default value of the validation attribute of all relevant instructions appearing within its scope. For details of the effect of this attribute, see 25.4 Validation.

The optional main-module attribute is purely documentary. By including this attribute in every stylesheet module of a package, an XSLT editing tool may be enabled to locate the top-level module of the relevant package, and thus to gather information about all the global variables, templates, and functions available within the module being edited. This information can be used (for example) to enable auto-completion and error highlighting of the code as it is entered. Note that it may be inconvenient or misleading to use this attribute when the stylesheet module is used as a shared component within multiple stylesheets.

[ERR XTSE0120] An xsl:stylesheet, xsl:transform, or xsl:package element must not have any text node children. (This rule applies after stripping of whitespace text nodes as described in 3.13.1 Stripping Whitespace and Commentary from the Stylesheet.)

[Definition: An element occurring as a child of an xsl:package, xsl:stylesheet, xsl:transform, or xsl:override element is called a top-level element.]

[Definition: Top-level elements fall into two categories: declarations, and user-defined data elements. Top-level elements whose names are in the XSLT namespace are declarations. Top-level elements in any other namespace are user-defined data elements (see 3.7.4 User-defined Data Elements)].

The declaration elements permitted in the xsl:stylesheet element are:

xsl:accumulator
xsl:attribute-set
xsl:character-map
xsl:decimal-format
xsl:function
xsl:global-context-item
xsl:import
xsl:import-schema
xsl:include
xsl:item-type
xsl:key
xsl:mode
xsl:namespace-alias
xsl:output
xsl:param
xsl:preserve-space
xsl:record-type
xsl:strip-space
xsl:template
xsl:use-package
xsl:variable

Note that the xsl:variable and xsl:param elements can act either as declarations or as instructions. A global variable or parameter is defined using a declaration; a local variable or parameter using an instruction.

The child elements of the xsl:stylesheet element may appear in any order. In most cases, the ordering of these elements does not affect the results of the transformation; however:

5 Features of the XSLT Language

5.3 The Static and Dynamic Context

XPath defines the concept of an expression contextXP which contains all the information that can affect the result of evaluating an expression. The expression context has two parts, the static contextXP, and the dynamic contextXP. The components that make up the expression context are defined in the XPath specification (see Section 2.2 Expression ContextXP). This section describes the way in which these components are initialized when an XPath expression is contained within an XSLT stylesheet.

This section does not apply to static expressions (whose context is defined in 9.7 Static Expressions), nor to XPath expressions evaluated using xsl:evaluate (whose context is defined in 10.4.2 Dynamic context for the target expression). [XSLT 3.0 Erratum E24, bug 30241]

As well as providing values for the static and dynamic context components defined in the XPath specification, XSLT defines additional context components of its own. These context components are used by XSLT instructions (for example, xsl:next-match and xsl:apply-imports), and also by the functions in the extended function library described in this specification.

The following four sections describe:

5.3.1 Initializing the Static Context
5.3.2 Additional Static Context Components used by XSLT
5.3.3 Initializing the Dynamic Context
5.3.4 Additional Dynamic Context Components used by XSLT

5.3.4 Additional Dynamic Context Components used by XSLT

In addition to the values that make up the focus, an XSLT processor maintains a number of other dynamic context components that reflect aspects of the evaluation context. These components are fully described in the sections of the specification that maintain and use them. They are:

The following non-normative table summarizes the initial state of each of the components in the evaluation context, and the instructions which cause the state of the component to change.

Components of the Dynamic Evaluation Context
ComponentInitial SettingSet byCleared by
focusSee 2.3 Initiating a Transformation.xsl:apply-templates, xsl:for-each, xsl:for-each-group, xsl:analyze-string, evaluation of patternsCalls to stylesheet functions
current template ruleIf apply-templates invocation is used (see 2.3.3 Apply-Templates Invocation), then for each item in the initial match selection, the current template rule is initially set to the template rule chosen for processing that item. Otherwise, absent. xsl:apply-templates, xsl:apply-imports, xsl:next-matchSee 6.96.8 Overriding Template Rules.
current modethe initial modexsl:apply-templatesCalls to stylesheet functions. Also cleared while evaluating global variables and stylesheet parameters, patterns, and the sequence constructor contained in xsl:key or xsl:sort. Clearing the current mode causes the current mode to be set to the default (unnamed) mode.
current groupabsentxsl:for-each-groupSee 14.2.1 fn:current-group.
current grouping keyabsentxsl:for-each-groupSee 14.2.2 fn:current-grouping-key.
current merge groupabsentxsl:mergeSee 15.6.1 fn:current-merge-group.
current merge keyabsentxsl:mergeSee 15.6.3 fn:current-merge-key and 15.6.2 fn:current-merge-key-array.
current captured substringsempty sequencexsl:matching-substringxsl:non-matching-substring; Calls to stylesheet functions, dynamic function calls, evaluation of global variables, stylesheet parameters, and patterns
output statefinal output stateSet to temporary output state by instructions such as xsl:variable, xsl:attribute, etc., and by calls on stylesheet functionsNone
current output URIbase output URIxsl:result-documentCalls to stylesheet functions, dynamic function calls, evaluation of global variables, stylesheet parameters, and patterns.

[Definition: The initial setting of a component of the dynamic context is used when evaluating global variables and stylesheet parameters, when evaluating the use and match attributes of xsl:key, and when evaluating the initial-value of xsl:accumulator and the select expressions or contained sequence constructors of xsl:accumulator-rule].

[Definition: The term non-contextual function call is used to refer to function calls that do not pass the dynamic context to the called function. This includes all calls on stylesheet functions and all dynamic function invocationsXP, (that is calls to function items as permitted by XPath 3.0). It excludes calls to some functions in the namespace http://www.w3.org/2005/xpath-functions, in particular those that explicitly depend on the context, such as the current-group and regex-group functions. It is implementation-defined whether, and under what circumstances, calls to extension functions are non-contextual.]

Named function references (such as position#0) and calls on function-lookup (for example, function-lookup("position", 0)) are defined to retain the XPath static and dynamic context at the point of invocation as part of the closure of the resulting function item, and to use this preserved context when a dynamic function call is subsequently made using the function item. This rule does not extend to the XSLT extensions to the dynamic context defined in this section. If a dynamic function call is made that depends on the XSLT part of the dynamic context (for example, regex-group#1(2)), then the relevant components of the context are cleared as described in the table above.

5.4 Patterns

In XSLT 4.0, patterns can match any kind of item: atomic items and function items as well as nodes.

A template rule identifies the items to which it applies by means of a pattern. As well as being used in template rules, patterns are used for numbering (see 12 Numbering), for grouping (see 14 Grouping), and for declaring keys (see 20.2 Keys).

[Definition: A pattern specifies a set of conditions on an item. An item that satisfies the conditions matches the pattern; an item that does not satisfy the conditions does not match the pattern.]

There are three kinds of pattern: predicate patterns, type patterns, and node patterns:

  • [Definition: A predicate pattern is written as . (dot) followed by zero or more predicates in square brackets, and it matches any item for which each of the predicates evaluates to true.]

    A predicate pattern .[P1][P2]... can be regarded as an abbreviation for the type pattern type(item())[P1][P2]....

    The detailed semantics are given in 5.4.2.1 Predicate Patterns. This construct can be used to match items of any kind (nodes, atomic items, and function items). For example, the pattern .[starts-with(., '$')] matches any string that starts with the character $, or a node whose atomized value starts with $. This example shows a predicate pattern with a single predicate, but the grammar allows any number of predicates (zero or more).

  • [Definition: A type pattern can be written as type(T) (where T is an ItemTypeXP followed by zero or more predicates in square brackets, and it matches any item of type T which each of the predicates evaluates to true.]

    The parameter T can also be a list of item types, separated by "|". For example, type(array(*) | map(*)) matches arrays and maps, while type(text() | comment()) matches text nodes and comment nodes.

    The most commonly used type patterns can be abbreviated. For example, match="type(record(F1, F2, *))" can be abbrevated to match="record(F1, F2, *)", and match="type(array(xs:string))" can be abbreviated to match="array(xs:string)". The main case where such abbreviation is not possible is with atomic items: match="type(xs:date)" cannot be abbreviated because a bare QName is interpreted as a node pattern, matching elements named xs:date. The pattern match="type(text() | comment())" has almost the same effect as match="text() | comment()", except that the rules for calculating a default priority are different.

  • [Definition: A node pattern uses a subset of the syntax for path expressions, and is defined to match a node if the corresponding path expression would select the node. Node patterns may also be formed by combining other patterns using union, intersection, and difference operators.]

    The syntax for node patterns (UnionExprP in the grammar: see 5.4.2 Syntax of Patterns) is a subset of the syntax for expressions. Node patterns are used only for matching nodes; an item other than a node will never match a node pattern. As explained in detail below, a node matches a node pattern if the node can be selected by deriving an equivalent expression, and evaluating this expression with respect to some possible context.

Note:

The specification uses the phrases an item matches a pattern and a pattern matches an item interchangeably. They are equivalent: an item matches a pattern if and only if the pattern matches the item.

5.4.2 Syntax of Patterns

[ERR XTSE0340] Where an attribute is defined to contain a pattern, it is a static error if the pattern does not match the production Pattern40.

The complete grammar for patterns is listed in E Pattern Syntax Summary. It uses the notation defined in Section A.1.1 NotationXP.

The lexical rules for patterns are the same as the lexical rules for XPath expressions, as defined in Section A.3 Lexical structureXP. Comments are permitted between tokens, using the syntax (: ... :). All other provisions of the XPath grammar apply where relevant, for example the rules for whitespace handling and extra-grammatical constraints.

Pattern40::=PredicatePattern | TypePattern | NodePattern | LabelPattern
PredicatePattern::="." PredicateXP*
TypePattern::=(WrappedItemTest | AnyItemTestXP | FunctionTypeXP | MapTypeXP | ArrayTypeXP | RecordTypeXP | EnumerationTypeXP) PredicateXP*
NodePattern::=UnionExprP
LabelPattern::=(("?" | "??") KeySpecifierP)+

Patterns fall into threefour groups:

  • A PredicatePattern matches items according to conditions that the item must satisfy: for example .[. castable as xs:integer] matches any value (it might be an atomic item, a node, or an array) that is castable as an integer.

  • A TypePattern matches items according to their type. For example type(xs:integer) matches an atomic item that is an instance of xs:integer, while record(longitude, latitude) matches a map that has exactly two entries, with keys "longitude" and "latitude"

  • A NodePattern matches nodes in a tree, typically by specifying a path that can be used to locate the nodes: for example order matches an element node named order, while billing-address/city matches an element named city whose parent node is an element named billing-address.

  • A LabelPattern matches items according to keys found in their labels. These arise typically when processing a tree of maps and arrays using xsl:apply-templates.

The following sections define the rules for each of these groups.:

5.4.2.1 Predicate Patterns
5.4.2.2 Type Patterns
5.4.2.3 Node Patterns
5.4.2.5 Label Patterns

5.4.2.5 Label Patterns

Changes in 4.0  

  1. Label patterns are new in XSLT 4.0. They are used for matching values occurring within a tree of maps and array, such as occurs as the result of parsing JSON.  [Issue 1776 ]

The syntax of a label pattern is:

LabelPattern::=(("?" | "??") KeySpecifierP)+
KeySpecifierP::=NCNameXP | IntegerLiteral | StringLiteralXP | VarRefXP | LookupWildcardXP | TypeSpecifierXP
IntegerLiteral::=Digits
/* ws: explicit */
Digits::=DecDigit ((DecDigit | "_")* DecDigit)?
/* ws: explicit */
DecDigit::=[0-9]
/* ws: explicit */
StringLiteral::=AposStringLiteral | QuotStringLiteral
/* ws: explicit */
AposStringLiteral::="'" (EscapeApos | [^'])* "'"
/* ws: explicit */
QuotStringLiteral::='"' (EscapeQuot | [^"])* '"'
/* ws: explicit */
VarRef::="$" EQNameXP
EQName::=QName | URIQualifiedNameXP
URIQualifiedName::=BracedURILiteralNCName
/* ws: explicit */
LookupWildcard::="*"
TypeSpecifier::="~[" SequenceTypeXP "]"
SequenceType::=("empty-sequence" "(" ")")
| (ItemTypeXPOccurrenceIndicatorXP?)
ItemType::=AnyItemTestXP | TypeNameXP | KindTestXP | FunctionTypeXP | MapTypeXP | ArrayTypeXP | RecordTypeXP | EnumerationTypeXP | ChoiceItemTypeXP
AnyItemTest::="item" "(" ")"
TypeName::=EQNameXP
KindTest::=DocumentTestXP
| ElementTestXP
| AttributeTestXP
| SchemaElementTestXP
| SchemaAttributeTestXP
| PITestXP
| CommentTestXP
| TextTestXP
| NamespaceNodeTestXP
| AnyKindTestXP
FunctionType::=AnyFunctionTypeXP
| TypedFunctionTypeXP
MapType::=AnyMapTypeXP | TypedMapTypeXP
ArrayType::=AnyArrayTypeXP | TypedArrayTypeXP
RecordType::=AnyRecordTypeXP | TypedRecordTypeXP
EnumerationType::="enum" "(" (StringLiteralXP ++ ",") ")"
ChoiceItemType::="(" (ItemTypeXP ++ "|") ")"
OccurrenceIndicator::="?" | "*" | "+"
/* xgs: occurrence-indicators */

Informally, an item J matches a pattern such as ?a?b?c if there is some containing map or array $C such that $C?a?b?c returns a result that includes the item J.

To take a simple example, given the input map

[
  { "Title": "Computer Architecture",
    "Authors": [ "Enid Blyton"] ,
    "Category": "Computers",
    "Price": 42.60
  },
  { "Title": "Steppenwolf",
    "Authors": [ "Hermann Hesse" ],
    "Category": "Fiction",
    "Price": 12.00
  },
  {  "Title": "How to Explore Outer Space with Binoculars",
     "Authors": [ "Bruce Betts", "Erica Colon" ],
     "Category": "Science",
     "Price": 10.40
  }
]
  • The values 42.60, 12.00, and 10.40 match the pattern ?Price

  • The value 12.00 matches the pattern ?2?Price

  • The strings "Enid Blyton", "Hermann Hesse", "Bruce Betts", and "Erica Colon" all match the pattern ?Authors?*

  • The strings "Enid Blyton", "Hermann Hesse", and "Bruce Betts" all match the pattern ?Authors?1

  • The arrays ["Enid Blyton"], ["Hermann Hesse"], and ["Bruce Betts", "Erica Colon"] all match the pattern ?Authors

  • The values 42.60, 12.00, and 10.40 match the pattern ?~record(Title, Author, Category, Price)?Price (this pattern might be used to distinguish prices of books from prices of other objects).

These patterns rely on the matched items being labeled, which will automatically be the case if they are selected in the course of evaluating an xsl:apply-templates instruction applied to a map or array, as described in 6.3.3 Applying Templates to Maps and Arrays.

A more precise definition of the semantics of a label pattern LL is that the pattern matches an item $J if the value of label($J)?ancestors() includes a map or array $A such that the expression LL, evaluated with $A as the context item, selects an item $K such that label($K)?id equals label($J)?id.

6 Template Rules

Template rules define the processing that can be applied to items that match a particular pattern.

6.2 Defining Template Rules

This section describes template rules. Named templates are described in 10.1 Named Templates.

A template rule is specified using the xsl:template element with a match attribute. The match attribute is a Pattern that identifies the items to which the rule applies. The result of applying the template rule is the result of evaluating the sequence constructor contained in the xsl:template element, with the matching item used as the context item.

Example: A Simple Template Rule

For example, an XML document might contain:

This is an <emph>important</emph> point.

The following template rule matches emph elements and produces a fo:wrapper element with a font-weight property of bold.

<xsl:template match="emph">
  <fo:wrapper font-weight="bold" 
              xmlns:fo="http://www.w3.org/1999/XSL/Format">
    <xsl:apply-templates/>
  </fo:wrapper>
</xsl:template>

A template rule is evaluated when an xsl:apply-templates instruction selects an item that matches the pattern specified in the match attribute. The xsl:apply-templates instruction is described in the next section. If several template rules match a selected item, only one of them is evaluated, as described in 6.56.4 Conflict Resolution for Template Rules.

6.3 Applying Template Rules

Changes in 4.0  

  1. 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.]   [  1 January 2022]

<!-- Category: instruction -->
<xsl:apply-templates
  select? = expression
  mode? = token
  separator? = { string } >
  <!-- Content: (xsl:sort | xsl:with-param)* -->
</xsl:apply-templates>

The xsl:apply-templates instruction takes as input a sequence of items (typically nodes in a source tree), and produces as output a sequence of items; these will often be nodes to be added to a result tree.

If the instruction has one or more xsl:sort children, then the input sequence is sorted as described in 13 Sorting. The result of this sort is referred to below as the sorted sequence; if there are no xsl:sort elements, then the sorted sequence is the same as the input sequence.

Each item in the input sequence is processed by finding a template rule whose pattern matches that item. If there is more than one such template rule, the best among them is chosen, using rules described in 6.56.4 Conflict Resolution for Template Rules. If there is no template rule whose pattern matches the item, a built-in template rule is used (see 6.86.7 Built-in Template Rules). The chosen template rule is evaluated. The rule that matches the Nth item in the sorted sequence is evaluated with that item as the context item, with N as the context position, and with the length of the sorted sequence as the context size. Each template rule that is evaluated produces a sequence of items as its result. The resulting sequences (one for each item in the sorted sequence) are then concatenated, to form a single sequence. They are concatenated retaining the order of the items in the sorted sequence. The final concatenated sequence forms the result of the xsl:apply-templates instruction.

Example: Applying Template Rules

Suppose the source document is as follows:

<message>Proceed <emph>at once</emph> to the exit!</message>

This can be processed using the two template rules shown below.

6.3.1 Applying Template Rules to Node Trees

This section illustrates common techniques used when template rules are used to transform XML documents, represented as node trees.

<xsl:template match="message">
  <p>
    <xsl:apply-templates select="child::node()"/>
  </p>
</xsl:template>

<xsl:template match="emph">
  <b>
    <xsl:apply-templates select="child::node()"/>
  </b>
</xsl:template>
Example: Applying Template Rules

Suppose the source document is as follows:

<message>Proceed <emph>at once</emph> to the exit!</message>

This can be processed using the two template rules shown below.

<xsl:template match="message">
  <p>
    <xsl:apply-templates select="child::node()"/>
  </p>
</xsl:template>

<xsl:template match="emph">
  <b>
    <xsl:apply-templates select="child::node()"/>
  </b>
</xsl:template>

There is no template rule for the document node; the built-in template rule for this node will cause the message element to be processed. The template rule for the message element causes a p element to be written to the result tree; the contents of this p element are constructed as the result of the xsl:apply-templates instruction. This instruction selects the three child nodes of the message element (a text node containing the value Proceed , an emph element node, and a text node containing the value to the exit!). The two text nodes are processed using the built-in template rule for text nodes, which returns a copy of the text node. The emph element is processed using the explicit template rule that specifies match="emph".

When the emph element is processed, this template rule constructs a b element. The contents of the b element are constructed by means of another xsl:apply-templates instruction, which in this case selects a single node (the text node containing the value at once). This is again processed using the built-in template rule for text nodes, which returns a copy of the text node.

The final result of the match="message" template rule thus consists of a p element node with three children: a text node containing the value Proceed , a b element that is the parent of a text node containing the value at once, and a text node containing the value to the exit!. This result tree might be serialized as:

<p>Proceed <b>at once</b> to the exit!</p>

There is no template rule for the document node; the built-in template rule for this node will cause the message element to be processed. The template rule for the message element causes a p element to be written to the result tree; the contents of this p element are constructed as the result of the xsl:apply-templates instruction. This instruction selects the three child nodes of the message element (a text node containing the value Proceed , an emph element node, and a text node containing the value to the exit!). The two text nodes are processed using the built-in template rule for text nodes, which returns a copy of the text node. The emph element is processed using the explicit template rule that specifies match="emph".

When the emph element is processed, this template rule constructs a b element. The contents of the b element are constructed by means of another xsl:apply-templates instruction, which in this case selects a single node (the text node containing the value at once). This is again processed using the built-in template rule for text nodes, which returns a copy of the text node.

The final result of the match="message" template rule thus consists of a p element node with three children: a text node containing the value Proceed , a b element that is the parent of a text node containing the value at once, and a text node containing the value to the exit!. This result tree might be serialized as:

The default value of the select attribute is child::node(), which causes all the children of the context node to be processed.

[ERR XTTE0510] It is a type error if an xsl:apply-templates instruction with no select attribute is evaluated when the context item is not a node.

A select attribute can be used to process items selected by an expression instead of processing all children. The value of the select attribute is an expression.

Example: Applying Templates to Selected Nodes

The following example processes all of the given-name children of the author elements that are children of author-group:

<xsl:template match="author-group">
  <fo:wrapper>
    <xsl:apply-templates select="author/given-name"/>
  </fo:wrapper>
</xsl:template>

 

Example: Applying Templates to Nodes that are not Descendants

It is also possible to process elements that are not descendants of the context node. This example assumes that a department element has group children and employee descendants. It finds an employee’s department and then processes the group children of the department.

<xsl:template match="employee">
  <fo:block>
    Employee <xsl:apply-templates select="name"/> belongs to group
    <xsl:apply-templates select="ancestor::department/group"/>
  </fo:block>
</xsl:template>

 

<p>Proceed <b>at once</b> to the exit!</p>
Example: Matching Nodes by Schema-Defined Types

It is possible to write template rules that are matched according to the schema-defined type of an element or attribute. The following example applies different formatting to the children of an element depending on their type:

<xsl:template match="product">
  <table>
    <xsl:apply-templates select="*"/>
  </table>
</xsl:template>

<xsl:template match="product/*" priority="3">
  <tr>
    <td><xsl:value-of select="name()"/></td>
    <td><xsl:next-match/></td>
  </tr>
</xsl:template>

<xsl:template match="product/element(*, xs:decimal) | 
                     product/element(*, xs:double)" priority="2">  
  <xsl:value-of select="format-number(xs:double(.), '#,###0.00')"/>
</xsl:template>

<xsl:template match="product/element(*, xs:date)" priority="2">
  <xsl:value-of select="format-date(., '[Mn] [D], [Y]')"/>
</xsl:template>

<xsl:template match="product/*" priority="1.5">
  <xsl:value-of select="."/>
</xsl:template>

The xsl:next-match instruction is described in 6.8 Overriding Template Rules.

 

Example: Re-ordering Elements in the Result Tree

Multiple xsl:apply-templates elements can be used within a single template to do simple reordering. The following example creates two HTML tables. The first table is filled with domestic sales while the second table is filled with foreign sales.

<xsl:template match="product">
  <table>
    <xsl:apply-templates select="sales/domestic"/>
  </table>
  <table>
    <xsl:apply-templates select="sales/foreign"/>
  </table>
</xsl:template>

 

Example: Processing Recursive Structures

It is possible for there to be two matching descendants where one is a descendant of the other. This case is not treated specially: both descendants will be processed as usual.

For example, given a source document

<doc><div><div></div></div></doc>

the rule

<xsl:template match="doc">
  <xsl:apply-templates select=".//div"/>
</xsl:template>

will process both the outer div and inner div elements.

This means that if the template rule for the div element processes its own children, then these grandchildren will be processed more than once, which is probably not what is required. The solution is to process one level at a time in a recursive descent, by using select="div" in place of select=".//div"

Note:

The xsl:apply-templates instruction is most commonly used to process nodes that are descendants of the context node. Such use of xsl:apply-templates cannot result in non-terminating processing loops. However, when xsl:apply-templates is used to process elements that are not descendants of the context node, the possibility arises of non-terminating loops. For example,

<xsl:template match="foo">
  <xsl:apply-templates select="."/>
</xsl:template>

Implementations may be able to detect such loops in some cases, but the possibility exists that a stylesheet may enter a non-terminating loop that an implementation is unable to detect. This may present a denial of service security risk.

The default value of the select attribute is child::node(), which causes all the children of the context node to be processed.

[ERR XTTE0510] It is a type error if an xsl:apply-templates instruction with no select attribute is evaluated when the context item is not a node.

A select attribute can be used to process items selected by an expression instead of processing all children. The value of the select attribute is an expression.

Example: Applying Templates to Selected Nodes

The following example processes all of the given-name children of the author elements that are children of author-group:

<xsl:template match="author-group">
  <fo:wrapper>
    <xsl:apply-templates select="author/given-name"/>
  </fo:wrapper>
</xsl:template>

 

Example: Applying Templates to Nodes that are not Descendants

It is also possible to process elements that are not descendants of the context node. This example assumes that a department element has group children and employee descendants. It finds an employee’s department and then processes the group children of the department.

<xsl:template match="employee">
  <fo:block>
    Employee <xsl:apply-templates select="name"/> belongs to group
    <xsl:apply-templates select="ancestor::department/group"/>
  </fo:block>
</xsl:template>

 

Example: Matching Nodes by Schema-Defined Types

It is possible to write template rules that are matched according to the schema-defined type of an element or attribute. The following example applies different formatting to the children of an element depending on their type:

<xsl:template match="product">
  <table>
    <xsl:apply-templates select="*"/>
  </table>
</xsl:template>

<xsl:template match="product/*" priority="3">
  <tr>
    <td><xsl:value-of select="name()"/></td>
    <td><xsl:next-match/></td>
  </tr>
</xsl:template>

<xsl:template match="product/element(*, xs:decimal) | 
                     product/element(*, xs:double)" priority="2">  
  <xsl:value-of select="format-number(xs:double(.), '#,###0.00')"/>
</xsl:template>

<xsl:template match="product/element(*, xs:date)" priority="2">
  <xsl:value-of select="format-date(., '[Mn] [D], [Y]')"/>
</xsl:template>

<xsl:template match="product/*" priority="1.5">
  <xsl:value-of select="."/>
</xsl:template>

The xsl:next-match instruction is described in 6.9 Overriding Template Rules.

 

Example: Re-ordering Elements in the Result Tree

Multiple xsl:apply-templates elements can be used within a single template to do simple reordering. The following example creates two HTML tables. The first table is filled with domestic sales while the second table is filled with foreign sales.

<xsl:template match="product">
  <table>
    <xsl:apply-templates select="sales/domestic"/>
  </table>
  <table>
    <xsl:apply-templates select="sales/foreign"/>
  </table>
</xsl:template>

 

Example: Processing Recursive Structures

It is possible for there to be two matching descendants where one is a descendant of the other. This case is not treated specially: both descendants will be processed as usual.

For example, given a source document

<doc><div><div></div></div></doc>

the rule

<xsl:template match="doc">
  <xsl:apply-templates select=".//div"/>
</xsl:template>

will process both the outer div and inner div elements.

This means that if the template rule for the div element processes its own children, then these grandchildren will be processed more than once, which is probably not what is required. The solution is to process one level at a time in a recursive descent, by using select="div" in place of select=".//div"

 

Example: Applying Templates to Atomic Items

This example reads a non-XML text file and processes it line-by-line, applying different template rules based on the content of each line:

6.3.2 Applying Template Rules to Atomic Items

Template rules can also be used to process atomic items.

<xsl:template name="main">
  <xsl:apply-templates select="unparsed-text-lines('input.txt')"/>
</xsl:template>

<xsl:template match="type(xs:string)[starts-with(., '==')]">
  <h2><xsl:value-of select="replace(., '==', '')"/></h2>
</xsl:template>

<xsl:template match="type(xs:string)[starts-with(., '::')]">
  <p class="indent"><xsl:value-of select="replace(., '::', '')"/></p>
</xsl:template>

<xsl:template match="type(xs:string)">
  <p class="body"><xsl:value-of select="."/></p>
</xsl:template>
Example: Applying Templates to Atomic Items

This example reads a non-XML text file and processes it line-by-line, applying different template rules based on the content of each line:

<xsl:template name="main">
  <xsl:apply-templates select="unparsed-text-lines('input.txt')"/>
</xsl:template>

<xsl:template match="type(xs:string)[starts-with(., '==')]">
  <h2><xsl:value-of select="replace(., '==', '')"/></h2>
</xsl:template>

<xsl:template match="type(xs:string)[starts-with(., '::')]">
  <p class="indent"><xsl:value-of select="replace(., '::', '')"/></p>
</xsl:template>

<xsl:template match="type(xs:string)">
  <p class="body"><xsl:value-of select="."/></p>
</xsl:template>

 

Example: Applying Templates to JSON Documents

This example reads a JSON data file and formats it as XHTML.

It takes the following JSON data as input:

6.3.3 Applying Templates to Maps and Arrays

Changes in 4.0  

  1. When arrays and maps are processed using xsl:apply-templates, they are pinned, making additional properties (such as the key of a map entry) available within match patterns.   [Issue 1776 ]

A tree of maps and arrays (often derived by parsing JSON) behaves differently from a tree of nodes (typically derived by parsing XML). If a value is located within a tree of maps and arrays by means of a lookup expression, the value that is retrieved contains no intrinsic identifying information. Specifically:

  • The value has no name. It might have been selected from a containing map using its unique key value, but the key is not part of the value in the way that a node name is part of a node.

  • The value has no parent. Having selected a value from a containing map, there is no way of discovering the containing map. There is no equivalent of the parent or ancestor axes that are available for nodes.

  • The value has no identity. If two values are found using different selection criteria (for example, finding all employees at a given location and all employees with a particular job title) there is no way of asking whether the two values are identical, unless there happens to be a property that is known to be unique.

These differences create challenges when processing a tree of maps and arrays using recursive-descent rule-based template matching. It makes it difficult to define patterns that can be used to match values and determine what processing to apply, and having matched values, it makes it difficult to use information that is not contained within the value itself, but elsewhere in the containing tree.

To address these difficulties, when the xsl:apply-templates instruction selects a map or array, the map or array is automatically pinned, by applying the pin function; the xsl:apply-templates logic is then applied to the pinned version of the map or array.

When a map or array is pinned, all values within the subtree are labeled with additional properties. Conceptually, a deep copy of the map or array is created, in which every value is labeled with information about its parent (containing) map or array, together with its key or index within that container. The label is accessible using the label function, but otherwise has no effect on the way the value is processed.

More specifically, the rules are as follows:

  1. Let C be the context item for evaluation of the xsl:apply-templates instruction, and let S be an item selected by the (explicit or implicit) select expression of the instruction.

  2. If C is pinned (that is, it has a label with the property pinned = true()), and S is pinned, and C and S have the same root, then S is used as is.

  3. Otherwise, S is replaced by fn:pin(S).

Note:

In a practical implementation, it is likely that these labels will be created on-the-fly when a value is actually selected within a containing map or array. There is no need to create labels for values that are never selected for processing.

In the terminology of computer science, a pinned tree of maps and arrays is a zipper data structure. At a high level of abstraction, navigation within a zipper structure returns pairs consisting of a data element itself, plus information about how the data element was reached. In the XDM model these are referred to as the value and the label.

Labels are attached only to items, not to sequences.

Example: A Simple JSON-to-HTML Transformation

To take a simple example, suppose the input is a map obtained by parsing the JSON text:

{ "first": "John",
  "last":  "Smith",
  "dob":   "1995-12-06"
}

and the stylesheet is to transform this into the HTML:

<table>
  <tr> <td>First name:</td>    <td>John</td>            </tr>
  <tr> <td>Last name:</td>     <td>SMITH</td>           </tr>
  <tr> <td>Date of birth:</td> <td>6 December 1995</td> </tr>
</table>

This can be achieved by writing template rules as follows:

<xsl:mode on-no-match="shallow-copy-all"/>
                  
<xsl:template match="?first">
  <tr><td>First name:</td>
      <td>{.}</td>
  </tr>
</xsl:template>

<xsl:template match="?last">
  <tr><td>First name:</td>
      <td>{upper-case(.)}</td>
  </tr>
</xsl:template>

<xsl:template match="?dob">
  <tr><td>Date of birth:</td>
      <td>{format-date(xs:date(.), "[D1] [MNn] [Y0001]")}</td>
  </tr>
</xsl:template>

<xsl:template match="xsl:initial-template">
  <table>
     <xsl:apply-templates select="parse-json('input.json')"/>
  </table>
</xsl:template>

The way this works is as follows.

  1. The xsl:apply-templates instruction causes the top-level map to be pinned. This means that the values (the strings "John", "Smith", and "1995-12-06") are labeled with various properties: the important property for this example is the corresponding key.

  2. There is no template rule matching the top-level map. Therefore the built-in template rule for a mode with on-no-match="shallow-copy-all" is activated. This rule effectively does <xsl:apply-templates select="?*"/>, which applies templates to the three values "John", "Smith", and "1995-12-06".

  3. The match pattern ?first matches any value labeled with the key "first".

  4. Within the template rule having this pattern, the context item is the string "John" (the string has a label, but this template rule makes no use of it). The text value template {.} therefore outputs the string "John".

Match patterns for matching values by their corresponding key can be more complex than this example illustrates. For further examples, see 5.4.2.5 Label Patterns.

As well as being useful within match patterns, the properties in a label can also be used within the body of the template rule. The label of a value can be retrieved (as a map) using the label function, and the individual properties can then be accessed using a lookup expression. For example, expressions that might be used within the body of a template rule to access properties of the context item include:

label(.)?keyThe key associated with the value in a map, or the index associated with the value in an array.
label(.)?positionThe position of an item within a map entry or array member.
label(.)?idA system-generated string that uniquely identifies this value within the subtree of the root map or array..
label(.)?parent()The containing map or array.
label(.)?ancestors()All containing maps or arrays, back to the root map or array, in innermost-to-outermost order.
label(.)?path()The keys (or array indexes) of this value and all containing maps and array, back to the root map or array, in outermost-to-innermost order.

For example, within the body of a template rule, it is possible to test whether the context item is contained (at any depth) within a map that has the entry "deleted" : true() using the expression:

[
  { "Title": "Computer Architecture",
    "Authors": [ "Enid Blyton"] ,
    "Category": "Computers",
    "Price": 42.60
  },
  { "Title": "Steppenwolf",
    "Authors": [ "Hermann Hesse" ],
    "Category": "Fiction",
    "Price": 12.00
  },
  {  "Title": "How to Explore Outer Space with Binoculars",
     "Authors": [ "Bruce Betts", "Erica Colon" ],
     "Category": "Science",
     "Price": 10.40
  }
]
if (label(.)?ancestors()?deleted) then ...

The following template rules are used. The setting expand-text="yes" is assumed:

It is also possible to use such expressions within a predicate in a match pattern.

When xsl:apply-templates selects a map or array that has no label, this map or array is treated as the root of a subtree of values reachable by navigating downwards to the contents of nested maps or arrays. Labeling these values conceptually makes a deep copy, in which all values at any depth are identifiable as belonging to this root.

By contrast, when xsl:apply-templates selects a map or array that has an existing label, the label is examined to see if it belongs to the same root as the current item. If it does, the label is retained: the selected item and its subtree is not relabeled. If however, the item's label is unrelated, then it is treated in the same way as an unlabeled item: it is copied and relabeled, with the effect that any existing labels are discarded.

Note:

Unlike the model for XML-derived nodes, maps and arrays do not have a unique and permanent parent. The item that is returned by the parent() function in the item's label is the container from which the item was selected. Two items selected by different routes will have different values returned by the parent() function. In practice, however, when processing a tree of maps and arrays derived from parsing a JSON text, this is unlikely to be a concern.

Decomposing a map or array using the expression <xsl:apply-templates select="?*"/> works well when the members of the array, or the values in the map, are all single items (which is always the case with parsed JSON, except when the JSON text includes nulls). The technique is less suitable when processing arrays or maps that contain sequences. For example, if the context item is the array [1, (2,3), ()], then ?* evaluates to the sequence of three items, 1, 2, 3. In such cases it may be better to decompose an array using array:members(.), or a map using map:pairs(.). It will often be more convenient to process the resulting values using xsl:for-each rather than xsl:apply-templates, though both are possible. Values extracted using array:members(.) or map:pairs(.) still have labels, just as items extracted using a lookup expression do.

<xsl:record-type name="book" extensible="yes">
  <xsl:field name="Title"/>
  <xsl:field name="Authors"/>
  <xsl:field name="Category"/>
</xsl:record-type>

<xsl:template name="xsl:initial-template">
  <xsl:apply-templates select="parse-json('input.json')"/>
</xsl:template>  

<xsl:template match="array(book)">
  <h1>Christmas Book Selection</h1>
  <table>
    <thead>
       <tr>
         <th>Title</th>
         <th>Authors</th>
         <th>Category</th>
         <th>Price</th>
       </tr>
    </thead>
    <tbody>
      <xsl:apply-templates select="?*"/>
    </tbody>
  </table>
</xsl:template>

<xsl:template match="type(book)">
  <tr>
    <td>{?Title}</td>
    <td>{?Authors?* => string-join(", ")}</td>
    <td>{?Category}</td>
    <td>${?Price}</td>
  </tr>
</xsl:template>
Example: Applying Templates to JSON Documents

This example reads a JSON data file and formats it as XHTML.

It takes the following JSON data as input:

[
  { "Title": "Computer Architecture",
    "Authors": [ "Enid Blyton"] ,
    "Category": "Computers",
    "Price": 42.60
  },
  { "Title": "Steppenwolf",
    "Authors": [ "Hermann Hesse" ],
    "Category": "Fiction",
    "Price": 12.00
  },
  {  "Title": "How to Explore Outer Space with Binoculars",
     "Authors": [ "Bruce Betts", "Erica Colon" ],
     "Category": "Science",
     "Price": 10.40
  }
]

The following template rules are used. The setting expand-text="yes" is assumed:

<xsl:record-type name="book" extensible="yes">
  <xsl:field name="Title"/>
  <xsl:field name="Authors"/>
  <xsl:field name="Category"/>
</xsl:record-type>

<xsl:template name="xsl:initial-template">
  <xsl:apply-templates select="parse-json('input.json')"/>
</xsl:template>  

<xsl:template match="array(book)">
  <h1>Christmas Book Selection</h1>
  <table>
    <thead>
       <tr>
         <th>Title</th>
         <th>Authors</th>
         <th>Category</th>
         <th>Price</th>
       </tr>
    </thead>
    <tbody>
      <xsl:apply-templates select="?*"/>
    </tbody>
  </table>
</xsl:template>

<xsl:template match="type(book)">
  <tr>
    <td>{?Title}</td>
    <td>{?Authors?* => string-join(", ")}</td>
    <td>{?Category}</td>
    <td>${?Price}</td>
  </tr>
</xsl:template>

Note:

The xsl:apply-templates instruction is most commonly used to process nodes that are descendants of the context node. Such use of xsl:apply-templates cannot result in non-terminating processing loops. However, when xsl:apply-templates is used to process elements that are not descendants of the context node, the possibility arises of non-terminating loops. For example,

6.3.4 The apply-templates Function

Changes in 4.0  

  1. A new function fn:apply-templates is introduced.  [Issue 2005 PR 2006 16 May 2025]

Sometimes it is useful to be able to apply templates from within an XPath expression. A common example is when using XPath expressions to construct maps and arrays. For example, an array of maps might be constructed by the following code:

<xsl:template match="foo">
  <xsl:apply-templates select="."/>
</xsl:template>
<xsl:array>
  <xsl:for-each select="*">
    <xsl:array-member>
      <xsl:map>
        <xsl:for-each select="@*">
          <xsl:map-entry key="local-name()">
            <xsl:apply-templates select="."/>
          </xsl:map-entry>
        </xsl:for-each>
      </xsl:map>
    </xsl:array-member>  
  </xsl:for-each>
</xsl:array>

Implementations may be able to detect such loops in some cases, but the possibility exists that a stylesheet may enter a non-terminating loop that an implementation is unable to detect. This may present a denial of service security risk.

Such code can become verbose, so XSLT 4.0 offers the alternative of writing it like this:

<xsl:select>
  array{ * ! map:build(@*, local-name#1, apply-templates#1) }
</xsl:select>

To make this possible, a subset of the functionality of the xsl:apply-templates instruction is available via the (XSLT-only) apply-templates function, whose specification follows.

6.3.4.1 fn:apply-templates
Summary

Applies template rules to selected items.

Signature
fn:apply-templates(
$selectas item()*,
$optionsas map(*)?:= {}
) as item()*
Properties

This function is deterministicFO, context-dependentFO, and focus-independentFO.

Rules

The function call apply-templates(X), used within an XPath expression, returns the same result as the instruction <xsl:apply-templates select="X"/>

The entries that may appear in the $options map are as follows. The option parameter conventionsFO apply.

<record>$params as map(xs:QName, item()*), $tunnel-params as map(xs:QName, item()*), $mode as (xs:QName | enum("#current", "#unnamed", "#default"))</record>
KeyValueMeaning

params?

Supplies values for non-tunnel parameters. Each entry in the params map binds a parameter (identified by an xs:QName value) to a supplied value.
  • Type: map(xs:QName, item()*)

  • Default: {}

tunnel-params?

Supplies values for tunnel parameters. Each entry in the tunnel-params map binds a tunnel parameter (identified by an xs:QName value) to a supplied value.
  • Type: map(xs:QName, item()*)

  • Default: {}

mode?

Selects the mode to be used. The value may be set to an xs:QName that matches a declared mode in the stylesheet, or to one of the special values #current, #unnamed, or #default.
  • Type: (xs:QName | enum("#current", "#unnamed", "#default"))

  • Default: "#default"

xs:QNameSelects a declared mode by name.
#currentSelects the current mode.
#unnamedSelects the unnamed mode.
#defaultSelects the default mode from the static context.

For each item in the value of the $select argument, the function finds the best matching template rule in the selected mode and invokes that template rule with the supplied parameters (if any). The result of the function is the sequence concatenation of the results of performing this process for each item in the selected input, in turn.

Error Conditions

Errors may arise in the same situations as for the xsl:apply-templates instruction: for example, if the xsl:mode declaration specifies on-no-match="fail" and no matching template rule is found.

[ERR XTDE0565] It is a dynamic error if a call on the apply-templates function selects a mode that is not explicitly declared in the containing package, or accepted from a used package, or whose visibility is private.

Note:

Modes are private by default: for a mode to be available for reference by the apply-templates function, it must be explicitly declared with visibility="public".

Notes

Unlike the xsl:apply-templates instruction, the name of the required mode, and the names of the supplied parameters, can be evaluated dynamically.

Examples

The function call:

apply-templates(*, {'mode': '#current', 'params': { #expand : false() } })

has the same effect as the instruction:

<xsl:apply-templates 
        select="*"
        mode="#current">
    <xsl:with-param name="expand" select="false()"/>
</xsl:apply-templates>

6.3.5 The separator attribute

If the separator attribute of xsl:apply-templates is present, then its effective value is inserted, as a text node, into the output sequence, immediately after the results of processing each item in the sorted sequence other than the last.

For example, if the ARTICLE element has a number of element children named AUTHOR, the following code will produce a sorted, comma-separated list of authors:

<xsl:template match="ARTICLE">
  <article>
     ...
     <xsl:text>Author(s): </xsl:text>
     <xsl:apply-templates select="AUTHOR" separator=", ">
       <xsl:sort select="LAST-NAME"/>
       <xsl:sort select="FIRST-NAME"/>
     </xsl:apply-templates>
     ...
  </article>
</xsl:template>
<xsl:template match="AUTHOR" expand-text="yes">
  <xsl:text>{FIRST-NAME} {LAST-NAME}</xsl:text>
</xsl:template>

The node identity of any text nodes that are inserted is implementation-dependent. Specifically, it is not defined whether all the text nodes inserted in the course of one evaluation of the instruction are identical to each other, nor whether they are identical to the text nodes inserted in the course of another evaluation of this instruction, nor whether they are identical to any other parentless text nodes having the same string value.

If the separator is a zero-length string, then a zero-length text node is inserted into the sequence. (If the sequence is used for constructing the value of a node, then zero-length text nodes will be discarded: see 5.8.2 Constructing Simple Content and 5.8.1 Constructing Complex Content.)

6.4 The separator attribute

If the separator attribute of xsl:apply-templates is present, then its effective value is inserted, as a text node, into the output sequence, immediately after the results of processing each item in the sorted sequence other than the last.

For example, if the ARTICLE element has a number of element children named AUTHOR, the following code will produce a sorted, comma-separated list of authors:

<xsl:template match="ARTICLE">
  <article>
     ...
     <xsl:text>Author(s): </xsl:text>
     <xsl:apply-templates select="AUTHOR" separator=", ">
       <xsl:sort select="LAST-NAME"/>
       <xsl:sort select="FIRST-NAME"/>
     </xsl:apply-templates>
     ...
  </article>
</xsl:template>
<xsl:template match="AUTHOR" expand-text="yes">
  <xsl:text>{FIRST-NAME} {LAST-NAME}</xsl:text>
</xsl:template>

The node identity of any text nodes that are inserted is implementation-dependent. Specifically, it is not defined whether all the text nodes inserted in the course of one evaluation of the instruction are identical to each other, nor whether they are identical to the text nodes inserted in the course of another evaluation of this instruction, nor whether they are identical to any other parentless text nodes having the same string value.

If the separator is a zero-length string, then a zero-length text node is inserted into the sequence. (If the sequence is used for constructing the value of a node, then zero-length text nodes will be discarded: see 5.8.2 Constructing Simple Content and 5.8.1 Constructing Complex Content.)

6.56.4 Conflict Resolution for Template Rules

It is possible for a selected item to match more than one template rule with a given modeM. When this happens, only one template rule is evaluated for the item. The template rule to be used is determined as follows:

  1. First, only the matching template rule or rules with the highest import precedence are considered. Other matching template rules with lower precedence are eliminated from consideration.

  2. Next, of the remaining matching rules, only those with the highest priority are considered. Other matching template rules with lower priority are eliminated from consideration.

    [Definition: The priority of a template rule is specified by the priority attribute on the xsl:template declaration. If no priority is specified explicitly for a template rule, its default priority is used, as defined in 6.66.5 Default Priority for Template Rules.]

    [ERR XTSE0530] The value of the priority attribute must conform to the rules for the xs:decimal type defined in [XML Schema Part 2]. Negative values are permitted.

  3. Next, if any of the remaining matching rules has a match pattern in the form of a TypePattern, then this set of rules is reduced as follows:

    1. Any rule with a match pattern that is not a type pattern is discarded. (That is, type patterns are chosen in preference to non-type patterns). Call the set of type patterns that remain R.

    2. A TypePattern comprises an ItemType and a possibly empty set of predicates.

    3. Any rule in R whose ItemType is a strict supertype of the ItemType of another rule in R is discarded. A type T is a strict supertype of another type U if U is a subtypeXP of T and T is not a subtypeXP of U.

    4. If there is a rule P in R whose ItemType is the same type as the ItemType of another rule Q in R, and if Q has one or more predicates while P has none, then P is discarded. A type T is the same type as another type U if T is a subtypeXP of U and U is a subtypeXP of T.

    5. If this process leaves a single rule, then that rule is chosen.

    Note:

    For example, this means that:

    • The match pattern type(xs:integer) is chosen in preference to type(xs:decimal) which in turn is chosen in preference to type(item()).

    • The match pattern type(xs:integer)[. gt 0] is chosen in preference to type(xs:integer) which in turn is chosen in preference to type(xs:decimal).

    • The match pattern type(xs:integer) is chosen in preference to type(xs:integer | xs:double) which in turn is chosen in preference to type(xs:numeric).

    • The match pattern record(longitude, latitude, altitude) is chosen in preference to the pattern record(longitude, latitude, *), which in turn is chosen in preference to the pattern type(map(*)).

  4. If this leaves more than one matching template rule, then:

    1. If the modeM has an xsl:mode declaration, and the attribute value on-multiple-match="fail" is specified in the mode declaration, a dynamic error is raised. The error is treated as occurring in the xsl:apply-templates instruction, and can be recovered by wrapping that instruction in an xsl:try instruction.

      [ERR XTDE0540] It is a dynamic error if the conflict resolution algorithm for template rules leaves more than one matching template rule when the declaration of the relevant mode has an on-multiple-match attribute with the value fail.

    2. Otherwise, of the matching template rules that remain, the one that occurs last in declaration order is used.

    Note:

    This was a recoverable error in XSLT 2.0, meaning that it was implementation-defined whether the error was raised, or whether the ambiguity was resolved by taking the last matching rule in declaration order. In XSLT 3.0 this situation is not an error unless the attribute value on-multiple-match="fail" is specified in the mode declaration. It is also possible to request warnings when this condition arises, by means of the attribute warning-on-multiple-match="yes".

6.66.5 Default Priority for Template Rules

Changes in 4.0  

  1. Default priorities are added for new forms of ElementTest and AttributeTest, for example element(p:*) and element(a|b).   [Issue 1394 PR 1442 15 September 2024]

  2. The default priority for a template rule using a union pattern has changed. This change may cause incompatible behavior.   [Issue 1770 ]

[Definition: If no priority attribute is specified on an xsl:template element, a default priority is computed, based on the syntax of the pattern supplied in the match attribute.] The rules are as follows.

  1. If the top-level pattern is a ParenthesizedExprP then the outer parentheses are effectively stripped; these rules are applied recursively to the UnionExprP contained in the ParenthesizedExprP.

  2. If the top-level pattern is a UnionExprP consisting of multiple alternatives separated by | or union, then the default priority is the maximum of the default priorities of the alternatives.

    Note:

    This is a backwards incompatible change from XSLT 3.0 and earlier versions, which treated the template rule as equivalent to multiple template rules with different priorities.

    The change is made because of the increasing complexity of extending the rule to patterns like @(a|b), or attribute(a|b, xs:integer) which are defined to be semantically identical to equivalent union patterns; and to prevent confusion with type patterns such as type(element(a)|element(b)), where different rules apply.

    The change affects any template rule with a union pattern that (a) has no explicit priority attribute, and (b) has multiple branches with different default priority. It is recommended that processors should output a compatibility warning when such template rules are encountered.

    The change has two effects. Firstly, if two alternatives in a union pattern have different priority (for example in a pattern such as a | b/c, the priority of one of the branches will be raised to that of the other branch. Secondly, in cases where the same item matches both branches, a call on xsl:next-match will never cause the same template rule to be evaluated repeatedly.

  3. If the top-level pattern is an IntersectExceptExprP containing two or more PathExprP operands separated by intersect or except operators, then the priority of the pattern is that of the first PathExprP.

  4. If the pattern is a PredicatePattern then its priority is 1 (one), unless there are no predicates, in which case the priority is −1 (minus one).

  5. If the pattern is a PathExprP taking the form /, then the priority is −0.5 (minus 0.5).

  6. If the pattern is a PathExprP taking the form of an EQName optionally preceded by a ForwardAxisP or has the form processing-instruction(StringLiteralXP) or processing-instruction(NCNameNames) optionally preceded by a ForwardAxisP, then the priority is 0 (zero).

  7. If the pattern is a PathExprP taking the form of an ElementTestXP or AttributeTestXP, optionally preceded by a ForwardAxisP, then the priority is as shown in the table below. In this table:

    • The symbols E, A, and T represent an arbitrary element name, attribute name, and type name respectively;

    • The symbol W represents a WildcardXP other than * (for example prefix:* or *:local);

    • The symbol * represents itself.

    The presence or absence of the symbol ? following a type name does not affect the priority.

    Default Priority of Patterns
    FormatPriorityNotes
    element()−0.5(equivalent to *)
    element(*)−0.5(equivalent to *)
    attribute()−0.5(equivalent to @*)
    attribute(*)−0.5(equivalent to @*)
    element(W)−0.25
    attribute(W)−0.25
    element(E)0(equivalent to E)
    element(*,T)0(matches by type only)
    attribute(A)0(equivalent to @A)
    attribute(*,T)0(matches by type only)
    element(W,T)0.125
    element(E,T)0.25(matches by name and type)
    schema-element(E)0.25(matches by substitution group and type)
    attribute(W,T)0.125
    attribute(A,T)0.25(matches by name and type)
    schema-attribute(A)0.25(matches by name and type)
  8. If the pattern is a PathExprP taking the form of a DocumentTestXP, then if it includes no ElementTestXP or SchemaElementTestXP the priority is −0.5. If it does include an ElementTestXP or SchemaElementTestXP, then the priority is the same as the priority of that ElementTestXP or SchemaElementTestXP, computed according to the table above.

  9. If the pattern is a PathExprP taking the form of an NCNameNames:*, BracedURILiteralXP*, or *:NCNameNames, optionally preceded by a ForwardAxisP, then the priority is −0.25. [XSLT 3.0 Erratum E37, bug 30375].

  10. If the pattern is a PathExprP taking the form of any other NodeTestXP, optionally preceded by a ForwardAxisP, then the priority is −0.5.

  11. If the pattern is a TypePattern, then the priority is 0 (zero).

  12. If the pattern is a LabelPattern, then the priority is 0 (zero).

  13. In all other cases, the priority is +0.5.

Note:

In many cases this means that highly selective patterns have higher priority than less selective patterns. The most common kind of pattern (a pattern that tests for a node of a particular kind, with a particular expanded QName or a particular type) has priority 0. The next less specific kind of pattern (a pattern that tests for a node of a particular kind and an expanded QName with a particular namespace URI) has priority −0.25. Patterns less specific than this (patterns that just test for nodes of a given kind) have priority −0.5. Patterns that specify both the name and the required type have a priority of +0.25, putting them above patterns that only specify the name or the type. Patterns more specific than this, for example patterns that include predicates or that specify the ancestry of the required node, have priority 0.5.

However, it is not invariably true that a more selective pattern has higher priority than a less selective pattern. For example, the priority of the pattern node()[self::*] is higher than that of the pattern salary. Similarly, the patterns attribute(*, xs:decimal) and attribute(*, xs:short) have the same priority, despite the fact that the latter pattern matches a subset of the nodes matched by the former. Therefore, to achieve clarity in a stylesheet it is good practice to allocate explicit priorities.

6.76.6 Modes

[Definition:  A mode is a set of template rules; when the xsl:apply-templates instruction selects a set of items for processing, it identifies the rules to be used for processing those items by nominating a mode, explicitly or implicitly.] Modes allow a node in a source tree (for example) to be processed multiple times, each time producing a different result. They also allow different sets of template rules to be active when processing different trees, for example when processing documents loaded using the document function (see 20.1 fn:document).

Modes are identified by an expanded QName; in addition to any named modes, there is always one unnamed mode available. Whether a mode is named or unnamed, its properties may be defined in an xsl:mode declaration. If a mode name is used (for example in an xsl:template declaration or an xsl:apply-templates instruction) and no declaration of that mode appears in the stylesheet, the mode is implicitly declared with default properties.

6.7.16.6.1 Declaring Modes

Changes in 4.0  

  1. The xsl:mode declaration acquires an attribute as="sequence-type" which declares the return type of all template rules in that mode.   [Issue 750 PR 751 16 October 2023]

  2. The xsl:mode declaration acquires an attribute copy-namespaces which determines whether or not the built-in template rule copies unused namespace bindings.   [Issue 1724  13 April 2025]

<!-- Category: declaration -->
<xsl:mode
  name? = eqname
  as? = sequence-type〔'item()*'〕
  streamable? = boolean〔'no'〕
  use-accumulators? = tokens〔''〕
  on-no-match? = "deep-copy" | "shallow-copy" | "shallow-copy-all" | "deep-skip" | "shallow-skip" | "text-only-copy" | "fail"〔'text-only-copy'〕
  on-multiple-match? = "use-last" | "fail"〔'use-last'〕
  warning-on-no-match? = boolean
  warning-on-multiple-match? = boolean
  typed? = boolean | "strict" | "lax" | "unspecified"〔'unspecified'〕
  copy-namespaces? = boolean〔'yes'〕
  visibility? = "public" | "private" | "final"〔'private'〕 >
  <!-- Content: (xsl:template*) -->
</xsl:mode>

[Definition: The unnamed mode is the default mode used when no mode attribute is specified on an xsl:apply-templates instruction or xsl:template declaration, unless a different default mode has been specified using the [xsl:]default-mode attribute of a containing element.]

Every mode other than the unnamed mode is identified by an expanded QName.

A stylesheet may contain multiple xsl:mode declarations and may include or import stylesheet modules that also contain xsl:mode declarations. The name of an xsl:mode declaration is the value of its name attribute, if any.

[Definition: All the xsl:mode declarations in a package that share the same name are grouped into a named mode definition; those that have no name are grouped into a single unnamed mode definition.]

The declared-modes attribute of the xsl:package element determines whether implicit mode declarations are allowed, as described in 3.5.4.1 Requiring Explicit Mode Declarations. If the package allows implicit mode declarations, then if a stylesheet does not contain a declaration of the unnamed mode, a declaration is implied equivalent to an xsl:mode element with no attributes. Similarly, if there is a mode that is named in an xsl:template or xsl:apply-templates element, or in the [xsl:]default-mode attribute of a containing element, and the stylesheet does not contain a declaration of that mode, then a declaration is implied comprising an xsl:mode element with a name attribute equal to that mode name, plus the attribute visibility="private".

The attributes of the xsl:mode declaration establish values for a number of properties of a mode. The allowed values and meanings of the attributes are given in the following table.

Attributes of the xsl:mode Element
AttributeValuesMeaning
nameAn EQNameSpecifies the name of the mode. If omitted, this xsl:mode declaration provides properties of the unnamed mode
asA SequenceTypeDeclares the type of value returned by all template rules in this mode. If any template rules in this mode declare their return type using an as attribute on xsl:template, the values must be consistent.
streamableyes or no (default no)Determines whether template rules in this mode are to be capable of being processed using streaming. If the value yes is specified, then the body of any template rule that uses this mode must conform to the rules for streamable templates given in 6.7.76.6.6 Streamable Templates.
use-accumulatorsList of accumulator names, or #all (default is an empty list)Relevant only when this mode is the initial mode of the transformation, determines which accumulators are applicable to documents containing nodes in the initial match selection. For further details see 18.2.2 Applicability of Accumulators.
on-no-matchOne of deep-copy, shallow-copy, deep-skip, shallow-skip, text-only-copy or fail (default text-only-copy)Determines selection of the built-in template rules that are used to process an item when an xsl:apply-templates instruction selects an item that does not match any user-written template rule in the stylesheet. For details, see 6.86.7 Built-in Template Rules.
on-multiple-matchOne of fail or use-last (default use-last)Defines the action to be taken when xsl:apply-templates is used in this mode and more than one user-written template rule is available to process an item, each having the same import precedence and priority. The value fail indicates that it is a dynamic error if more than one template rule matches an item. The value use-last indicates that the situation is not to be treated as an error (the last template in declaration order is the one that is used).
warning-on-no-matchOne of yes or no. The default is implementation-definedRequests the processor to output (or not to output) a warning message in the case where an xsl:apply-templates instruction selects an item that matches no user-written template rule. The form and destination of such warnings is implementation-defined. The processor may ignore this attribute, for example if the environment provides no suitable means of communicating with the user.
warning-on-multiple-matchOne of yes or no. The default is implementation-definedRequests the processor to output a warning message in the case where an xsl:apply-templates instruction selects an item that matches multiple template rules having the same import precedence and priority. The form and destination of such warnings is implementation-defined. The processor may ignore this attribute, for example if the environment provides no suitable means of communicating with the user.
typedOne of yes, no, strict, lax, or unspecified. The default is unspecified.See 6.7.46.6.3 Declaring the Type of Nodes Processed by a Mode.
copy-namespacesOne of yes or no. The default is yes.If on-no-match is shallow-copy, shallow-copy-all, or deep-copy, this attribute determines the effective value of the copy-namespaces attribute on the implicit xsl:copy or xsl:copy-of instruction in the built-in template rule (see 6.86.7 Built-in Template Rules). In other cases it is ignored, apart from checking that its value is valid.
visibilityOne of public, private, or final. The default is private.See 3.5.3.1 Visibility of Components. If the mode is unnamed, that is, if the name attribute is absent, then the visibility attribute if present must have the value private.
Editorial note 
See issue 270.

[Definition: A streamable mode is a mode that is declared in an xsl:mode declaration with the attribute streamable="yes".]

For any named mode, the effective value of each attribute is taken from an xsl:mode declaration that has a matching name in its name attribute, and that specifies an explicit value for the required attribute. If there is no such declaration, the default value of the attribute is used. If there is more than one such declaration, the one with highest import precedence is used.

For the unnamed mode, the effective value of each attribute is taken from an xsl:mode declaration that has no name attribute, and that specifies an explicit value for the required attribute. If there is no such declaration, the default value of the attribute is used. If there is more than one such declaration, the one with highest import precedence is used.

[ERR XTSE0545] It is a static error if for any named or unnamed mode, a package explicitly specifies two conflicting values for the same attribute in different xsl:mode declarations having the same import precedence, unless there is another definition of the same attribute with higher import precedence. The attributes in question are the attributes other than name on the xsl:mode element.

6.7.26.6.2 Using Modes

[Definition: A template rule is applicable to one or more modes. The modes to which it is applicable are defined by the mode attribute of the xsl:template element. If the attribute is omitted, then the template rule is applicable to the default mode specified in the [xsl:]default-mode attribute of the innermost containing element that has such an attribute, which in turn defaults to the unnamed mode. If the mode attribute is present, then its value must be a non-empty whitespace-separated list of tokens, each of which defines a mode to which the template rule is applicable.]

Each token in the mode attribute must be one of the following:

  • An EQName, which is expanded as described in 5.1.1 Qualified Names to define the name of the mode

  • The token #default, to indicate that the template rule is applicable to the default mode that would apply if the mode attribute were absent

  • The token #unnamed, to indicate that the template rule is applicable to the unnamed mode

  • The token #all, to indicate that the template rule is applicable to all modes other than enclosing modes (specifically, to the unnamed mode and to every mode that is named explicitly or implicitly in an xsl:apply-templates instruction anywhere in the stylesheet).

    More specifically, when a template rule specifies mode="#all" this makes the template rule applicable to:

    The value mode="#all" cannot be used on a template rule declared within an xsl:overrideor xsl:mode element.

[ERR XTSE0550] It is a static error if the list of modes is empty, if the same token is included more than once in the list, if the list contains an invalid token, or if the token #all appears together with any other value.

[ERR XTSE3440] In the case of a template rule (that is, an xsl:template element having a match attribute) appearing as a child of xsl:override, it is a static error if the list of modes in the mode attribute contains #all or #unnamed, or if it contains #default and the default mode is the unnamed mode, or if the mode attribute is omitted when the default mode is the unnamed mode.

The xsl:apply-templates element also has an optional mode attribute. The value of this attribute must be one of the following:

  • an EQName, which is expanded as described in 5.1.1 Qualified Names to define the name of a mode

  • the token #default, to indicate that the default mode from the static context of the instruction is to be used

  • the token #unnamed, to indicate that the unnamed mode is to be used

  • the token #current, to indicate that the current mode is to be used

If the attribute is omitted, the default mode from the static context of the instruction is used.

When searching for a template rule to process each item selected by the xsl:apply-templates instruction, only those template rules that are applicable to the selected mode are considered.

[Definition: At any point in the processing of a stylesheet, there is a current mode. When the transformation is initiated, the current mode is the initial mode, as described in 2.3 Initiating a Transformation. Whenever an xsl:apply-templates instruction is evaluated, the current mode becomes the mode selected by this instruction.] When a non-contextual function call is made, the current mode is set to the unnamed mode. While evaluating global variables and parameters, and the sequence constructor contained in xsl:key or xsl:sort, the current mode is set to the unnamed mode. No other instruction changes the current mode. The current mode while evaluating an attribute set is the same as the current mode of the caller. On completion of the xsl:apply-templates instruction, or on return from a stylesheet function call, the current mode reverts to its previous value. The current mode is used when an xsl:apply-templates instruction uses the syntax mode="#current"; it is also used by the xsl:apply-imports and xsl:next-match instructions (see 6.96.8 Overriding Template Rules).

6.7.3 The apply-templates Function

Changes in 4.0  

  1. A new function fn:apply-templates is introduced.  [Issue 2005 PR 2006 16 May 2025]

Sometimes it is useful to be able to apply templates from within an XPath expression. A common example is when using XPath expressions to construct maps and arrays. For example, an array of maps might be constructed by the following code:

<xsl:array>
  <xsl:for-each select="*">
    <xsl:array-member>
      <xsl:map>
        <xsl:for-each select="@*">
          <xsl:map-entry key="local-name()">
            <xsl:apply-templates select="."/>
          </xsl:map-entry>
        </xsl:for-each>
      </xsl:map>
    </xsl:array-member>  
  </xsl:for-each>
</xsl:array>

Such code can become verbose, so XSLT 4.0 offers the alternative of writing it like this:

<xsl:sequence select="array{ * ! map:build(@*, local-name#1, apply-templates#1) }"/>

To make this possible, a subset of the functionality of the xsl:apply-templates instruction is available via the (XSLT-only) apply-templates function, whose specification follows.

6.7.3.1 fn:apply-templates
Summary

Applies template rules to selected items.

Signature
fn:apply-templates(
$selectas item()*,
$optionsas map(*)?:= {}
) as item()*
Properties

This function is deterministicFO, context-dependentFO, and focus-independentFO.

Rules

The function call apply-templates(X), used within an XPath expression, returns the same result as the instruction <xsl:apply-templates select="X"/>

The entries that may appear in the $options map are as follows. The option parameter conventionsFO apply.

<record>$params as map(xs:QName, item()*), $tunnel-params as map(xs:QName, item()*), $mode as (xs:QName | enum("#current", "#unnamed", "#default"))</record>
KeyValueMeaning

params?

Supplies values for non-tunnel parameters. Each entry in the params map binds a parameter (identified by an xs:QName value) to a supplied value.
  • Type: map(xs:QName, item()*)

  • Default: {}

tunnel-params?

Supplies values for tunnel parameters. Each entry in the tunnel-params map binds a tunnel parameter (identified by an xs:QName value) to a supplied value.
  • Type: map(xs:QName, item()*)

  • Default: {}

mode?

Selects the mode to be used. The value may be set to an xs:QName that matches a declared mode in the stylesheet, or to one of the special values #current, #unnamed, or #default.
  • Type: (xs:QName | enum("#current", "#unnamed", "#default"))

  • Default: "#default"

xs:QNameSelects a declared mode by name.
#currentSelects the current mode.
#unnamedSelects the unnamed mode.
#defaultSelects the default mode from the static context.

For each item in the value of the $select argument, the function finds the best matching template rule in the selected mode and invokes that template rule with the supplied parameters (if any). The result of the function is the sequence concatenation of the results of performing this process for each item in the selected input, in turn.

Error Conditions

Errors may arise in the same situations as for the xsl:apply-templates instruction: for example, if the xsl:mode declaration specifies on-no-match="fail" and no matching template rule is found.

[ERR XTDE0565] It is a dynamic error if a call on the apply-templates function selects a mode that is not explicitly declared in the containing package, or accepted from a used package, or whose visibility is private.

Note:

Modes are private by default: for a mode to be available for reference by the apply-templates function, it must be explicitly declared with visibility="public".

Notes

Unlike the xsl:apply-templates instruction, the name of the required mode, and the names of the supplied parameters, can be evaluated dynamically.

Examples

The function call:

apply-templates(*, {'mode': '#current', 'params': { #expand : false() } })

has the same effect as the instruction:

<xsl:apply-templates 
        select="*"
        mode="#current">
    <xsl:with-param name="expand" select="false()"/>
</xsl:apply-templates>

6.7.46.6.3 Declaring the Type of Nodes Processed by a Mode

Typically the template rules in a particular mode will be designed to process a specific kind of input document. The typed attribute of xsl:mode gives the stylesheet author the opportunity to provide information about this document to the processor. This information may enable the processor to improve diagnostics or to optimize performance.

The typed attribute of xsl:mode informs the processor whether the nodes to be processed by template rules in this mode are to be typed or untyped.

  • If the value yes is specified (synonyms true or 1), then all nodes processed in this mode must be typed. A dynamic error occurs if xsl:apply-templates in this mode selects an element or attribute node whose type annotation is xs:untyped or xs:untypedAtomic.

  • If the value no is specified (synonyms false or 0), then all nodes processed in this mode must be untyped. A dynamic error occurs if xsl:apply-templates in this mode selects an element or attribute whose type annotation is anything other than xs:untyped or xs:untypedAtomic.

  • The value strict is equivalent to yes, with the additional provision that in the match pattern of any template rule that is applicable to this mode, any NameTest used in the ForwardStepP of the first StepExprP of a RelativePathExprP is interpreted as follows:

    • If the NameTest is an EQNameE, and the principal node kind of the axis of this step is Element, then:

      • It is a static error if the in-scope schema declarations do not include a global element declaration for element name E

      • When matching templates in this mode, the element name E appearing in this step is interpreted as schema-element(E). (Informally, this means that it will only match an element if it has been validated against this element declaration).

    • Otherwise (the NameTest is a wildcard or the principal node kind is Attribute or Namespace), the template matching proceeds as if the typed attribute were absent.

  • The value lax is equivalent to yes, with the additional provision that in the match pattern of any template rule that is applicable to this mode, any NameTest used in the ForwardStepP of the first StepExprP of a RelativePathExprP is interpreted as follows:

    • If the NameTest is an EQNameE, and the principal node kind of the axis of this step is Element, and the in-scope schema declarations include a global element declaration for element name E, then:

      • When matching templates in this mode, the element name E appearing in this step is interpreted as schema-element(E). (Informally, this means that it will only match an element if it has been validated against this element declaration).

    • Otherwise (the NameTest is a wildcard, or the principal node kind is Attribute or Namespace, or there is no element declaration for E), the template matching proceeds as if the typed attribute were absent.

[ERR XTTE3100] It is a type error if an xsl:apply-templates instruction in a particular mode selects an element or attribute whose type is xs:untyped or xs:untypedAtomic when the typed attribute of that mode specifies the value yes, strict, or lax.

[ERR XTSE3105] It is a static error if a template rule applicable to a mode that is defined with typed="strict" uses a match pattern that contains a RelativePathExprP whose first StepExprP is an AxisStepP whose ForwardStepP uses an axis whose principal node kind is Element and whose NodeTest is an EQName that does not correspond to the name of any global element declaration in the in-scope schema components.

[ERR XTTE3110] It is a type error if an xsl:apply-templates instruction in a particular mode selects an element or attribute whose type is anything other than xs:untyped or xs:untypedAtomic when the typed attribute of that mode specifies the value no.

6.7.56.6.4 Declaring the Result Type of a Mode

Changes in 4.0  

  1. 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.   [Issues 233 750 1382 PRs 751 1386]

Traditionally, template rules have most commonly been used to construct XDM nodes, and the xsl:apply-templates instruction has been used to add nodes to a result tree. However, it is also possible to use template rules to produce other kinds of value, for example strings, booleans, or maps. For the xsl:apply-templates instruction to be useful, it will generally be the case that all template rules in a mode produce the same kind of value: for example, if one rule delivers a boolean, then the other rules will also deliver a boolean.

XSLT 4.0 therefore allows the result type of the template rules in a mode to be declared using the as attribute on the xsl:mode declaration. If this is absent, it defaults to item()*. The presence of an as attribute on a mode provides useful documentation and consistency checking, and enables the XSLT processor to infer a static type for an xsl:apply-templates instruction, which can be useful for optimization.

If a template rule R is applicable to a mode M, and M is declared with an as attribute whose value is the SequenceTypeT, then:

  • If R has an as attribute, the SequenceTypeS declared by R must be a subtype of T.

    [ERR XTSE4040] It is a static error if a template ruleR has an as attribute S, and the template rule is applicable to a modeM that is declared with an as attribute T, and the sequence type S is not a subtype of the sequence type T as defined by the relationship subtype(S, T) in Section 3.3.1 Subtypes of Sequence TypesXP.

  • If R has no as attribute, then it is treated as if it had an as attribute set to T. This means that a type error[see ERR XTTE0505] is raised if the result of the template rule cannot be coerced to a value of type T.

    If R is applicable to more than one mode, then it must meet the requirements of each one, which implies that these requirements must be consistent with each other: for example, if one mode specifies as="node()" and another specifies as="map(*)", then a type error is inevitable if the template rule is actually evaluated, and like other type errors this can be raised statically if detected statically. An implausibilityXPmay be reported if the only value that would satisfy both types is an empty sequence, map, or array.

    Note:

    In practice the best way to satisfy this rule is to ensure that if a template rule is applicable to more than one mode (including the case mode="#all"), then either (a) all those modes should have the same declared result type, or (b) the template rule should declare an explicit result type that is compatible with each one of the relevant modes.

  • The requirement to return values of the correct type extends also to the built-in template rule for the mode (see 6.86.7 Built-in Template Rules). Since it is not possible to determine statically whether the explicit template rules for a mode provide complete coverage of all possible inputs, any failure of the built-in template rule to return a value that can be coerced to the expected type must be raised dynamically [see ERR XTTE0505].

6.7.66.6.5 Enclosing Modes

Changes in 4.0  

  1. 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.   [Issue 82 PR 542 20 June 2023]

[Definition: A mode declared by an xsl:mode declaration that has one or more contained xsl:template declarations is referred to as an enclosing mode.]

An enclosing mode ensures that all the template rules for a mode are together in one place, which makes it easier for someone reading the stylesheet to establish what is going to happen when an xsl:apply-templates instruction in that mode is evaluated.

An enclosing mode must satisfy the following rules:

  1. The mode must have a name.

  2. Every contained xsl:template element must have a match attribute and no name attribute.

  3. Every contained xsl:template element must have no mode attribute: the template is implicitly applicable only to the containing mode.

  4. An xsl:mode declaration with one or more xsl:template children effectively has a default-mode attribute whose value is the mode’s name; it must not have a default-mode attribute with any other value.

    Note:

    This means that xsl:apply-templates instructions within the template rules of the enclosing mode default to using the enclosing mode.

  5. No xsl:template that is in the same package as the containing mode, but not declared within the containing mode, may be applicable to the containing mode.

    Note:

    Template rules in an enclosing mode may, however, be overridden within an xsl:override element in a using package.

  6. There must be no other xsl:mode declaration in the containing package having the same name and the same import precedence.

These rules give rise to the following error conditions:

[ERR XTSE4005] It is a static error if an xsl:mode declaration with one or more xsl:template children has no name attribute.

[ERR XTSE4010] It is a static error if an xsl:mode declaration has a child xsl:template element with a name attribute, with a mode attribute, or with no match attribute.

[ERR XTSE4015] It is a static error if an xsl:mode declaration having one or more child xsl:template elements has a default-mode attribute whose value differs from its name attribute, or if any of those child xsl:template elements has a default-mode attribute that differs from the name attribute of the xsl:mode declaration.

[ERR XTSE4020] It is a static error if a package contains both (a) an xsl:mode declaration having one or more child xsl:template elements, and (b) an xsl:template declaration that is not one of those children but that references that xsl:mode declaration in its mode attribute.

[ERR XTSE4025] It is a static error if a package contains (a) an xsl:mode declaration having one or more child xsl:template elements, and (b) a second xsl:mode declaration having the same name and the same import precedence.

Example: An Enclosing Mode

The following mode might be used for formatting of numbers appearing in text:

<xsl:mode name="numbers-in-text" as="xs:string" visibility="final">
  <xsl:template match="type(xs:integer)[. gt 0 and . lt 21]">
    <xsl:number value="." format="w"/>
  </xsl:template>
  <xsl:template match="type(xs:integer)[. lt 10000]">
    <xsl:number value="." format="1"/>
  </xsl:template>
  <xsl:template match="type(xs:integer)">
    <xsl:number value="." format="1" grouping-separator="," grouping-size="3"/>
  </xsl:template>  
</xsl:mode>

6.7.76.6.6 Streamable Templates

A template rule that is applicable to a mode M is guaranteed-streamable if and only if all the following conditions are satisfied:

  1. Mode M is declared in an xsl:mode declaration that specifies streamable="yes".

  2. The pattern defined in the match attribute of the xsl:template element is a motionless pattern as defined in 19.8.10 Classifying Patterns.

  3. The sweep of the sequence constructor forming the body of the xsl:template element is either motionless or consuming.

  4. The type-adjusted posture of the sequence constructor forming the body of the xsl:template element, with respect to the U-type that corresponds to the declared return type of the template (defaulting to item()*), is grounded.

    Note:

    This means that either (a) the sequence constructor is grounded as written (that is, it does not return streamed nodes), or (b) it effectively becomes grounded because the declared result type of the template is atomic, leading to implicit atomization of the result.

  5. Every expression and contained sequence constructor in a contained xsl:param element (the construct that provides the default value of the parameter) is motionless.

Specifying streamable="yes" on an xsl:mode declaration declares an intent that every template rule to which that mode is applicable (explicitly or implicitly, including by specifying #all), should be streamable, either because it is guaranteed-streamable, or because it takes advantage of streamability extensions offered by a particular processor. The consequences of declaring the mode to be streamable when there is such a template rule that is not guaranteed streamable depend on the conformance level of the processor, and are explained in 19.10 Streamability Guarantees.

Processing of a document using streamable templates may be initiated using code such as the following, where S is a mode declared with streamable="yes":

<xsl:source-document streamable="yes" href="bigdoc.xml">
  <xsl:apply-templates mode="S"/>
</xsl:source-document>

Alternatively, streamed processing may be initiated by invoking the transformation with an initial mode declared as streamable, while supplying the initial match selection (in an implementation-defined way) as a streamed document.

Note:

Invoking a streamable template using the construct <xsl:apply-templates select="doc('bigdoc.xml')"/> does not ensure streamed processing. As always, processors may use streamed processing if they are able to do so, but when the doc or document functions are used, processors are obliged to ensure that the results are deterministic, which may be difficult to reconcile with streaming (if the same document is read twice, the results must be identical). The use of xsl:source-document with streamable="yes" does not offer the same guarantees of determinism.

For an example of processing a collection of documents by use of the function uri-collection in conjunction with xsl:source-document, see 18.1.2 Examples of xsl:source-document.

6.86.7 Built-in Template Rules

Changes in 4.0  

  1. 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.   [Issue 570 PR 718 26 September 2023]

When an item is selected by xsl:apply-templates and there is no user-specified template rule in the stylesheet that can be used to process that item, then a built-in template rule is evaluated instead.

The built-in template rules have lower import precedence than all other template rules. Thus, the stylesheet author can override a built-in template rule by including an explicit template rule.

There are seven sets of built-in template rules available. The set that is chosen is a property of the mode selected by the xsl:apply-templates instruction. This property is set using the on-no-match attribute of the xsl:mode declaration, which takes one of the values deep-copy, shallow-copy, shallow-copy-all,deep-skip, shallow-skip, text-only-copy, or fail, the default being text-only-copy. The effect of these seven sets of built-in template rules is explained in the following subsections.

6.8.16.7.1 Built-in Templates: Text-only Copy

The effect of processing a tree using a mode that specifies on-no-match="text-only-copy" is that the textual content of the source document is retained while losing the markup, except where explicit template rules dictate otherwise. When an element is encountered for which there is no explicit template rule, the processing continues with the children of that element. Text nodes are copied to the output.

The built-in rule for document nodes and element nodes is equivalent to calling xsl:apply-templates with no select attribute, and with the mode attribute set to #current. If the built-in rule was invoked with parameters, those parameters are passed on in the implicit xsl:apply-templates instruction.

This is equivalent to the following in the case where there are no parameters:

<xsl:template match="document-node()|element()" mode="M">
  <xsl:apply-templates mode="#current"/>
</xsl:template>

The built-in template rule for text and attribute nodes returns a text node containing the string value of the context node. It is effectively:

<xsl:template match="text()|@*" mode="M">
  <xsl:value-of select="string(.)"/>
</xsl:template>

Note:

This text node may have a string value that is zero-length.

The built-in template rule for atomic items returns a text node containing the value. It is effectively:

<xsl:template match=".[. instance of xs:anyAtomicType]" mode="M">
  <xsl:value-of select="string(.)"/>
</xsl:template>

Note:

This text node may have a string value that is zero-length.

The built-in template rule for processing instructions, comments, and namespace nodes does nothing (it returns the empty sequence).

<xsl:template 
   match="processing-instruction()|comment()|namespace-node()" 
   mode="M"/>

The built-in template rule for functions (including maps) does nothing (it returns the empty sequence).

<xsl:template 
   match=".[. instance of fn(*)]" 
   mode="M"/>

The built-in template rule for arrays (see 22 Arrays) is to apply templates to the members of the array. It is equivalent to invoking xsl:apply-templates with the select attribute set to ?* (which selects the members of the array), and with the mode attribute set to #current. If the built-in rule was invoked with parameters, those parameters are passed on in the implicit xsl:apply-templates instruction.

This is equivalent to the following in the case where there are no parameters:

<xsl:template match=".[. instance of array(*)]" mode="M">
  <xsl:apply-templates mode="#current" select="?*"/>
</xsl:template>

The following example illustrates the use of built-in template rules when there are parameters.

Example: Using a Built-In Template Rule

Suppose the stylesheet contains the following instruction:

<xsl:apply-templates select="title" mode="M">
  <xsl:with-param name="init" select="10"/>
</xsl:apply-templates>

If there is no explicit template rule that matches the title element, then the following implicit rule is used:

<xsl:template match="title" mode="M">
  <xsl:param name="init"/>
  <xsl:apply-templates mode="#current">
    <xsl:with-param name="init" select="$init"/>
  </xsl:apply-templates>
</xsl:template>

6.8.26.7.2 Built-in Templates: Deep Copy

The effect of processing a tree using a mode that specifies on-no-match="deep-copy" is that an unmatched element in the source tree is copied unchanged to the output, together with its entire subtree. Other unmatched items are also copied unchanged. The subtree is copied unconditionally, without attempting to match nodes in the subtree against template rules.

When this default action is selected for a mode M, all items (nodes, atomic items, and functions, including maps and arrays) are processed using a template rule that is equivalent to the following:

<xsl:template match="." mode="M">
  <xsl:copy-of select="." validation="preserve" copy-namespaces="CN"/>
</xsl:template>

where CN is the value of the copy-namespaces attribute of the relevant xsl:mode declaration, defaulting to yes.

6.8.36.7.3 Built-in Templates: Shallow Copy

The effect of processing a tree using a mode that specifies on-no-match="shallow-copy" is that the source tree is copied unchanged to the output, except for nodes where different processing is specified using an explicit template rule.

When this default action is selected for a mode M, all items (nodes, atomic items, and functions, including maps and arrays) are processed using a template rule that is equivalent to the following, except that all parameters supplied in xsl:with-param elements are passed on implicitly to the called templates:

<xsl:template match="." mode="M">
  <xsl:copy validation="preserve" copy-namespaces="CN">
    <xsl:apply-templates select="@*" mode="M"/>
    <xsl:apply-templates select="node()" mode="M"/>
  </xsl:copy>
</xsl:template>

where CN is the value of the copy-namespaces attribute of the relevant xsl:mode declaration, defaulting to yes.

This rule is often referred to as the identity template, though it should be noted that it does not preserve node identity.

Note:

This rule differs from the traditional identity template rule by using two xsl:apply-templates instructions, one to process the attributes and one to process the children. The only observable difference from the traditional select="node() | @*" is that with two separate instructions, the value of position() in the called templates forms one sequence starting at 1 for the attributes, and a new sequence starting at 1 for the children.

Example: Modified Identity Transformation

The following stylesheet transforms an input document by deleting all elements named note, together with their attributes and descendants:

<xsl:stylesheet version="3.0"
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
				  
<xsl:mode on-no-match="shallow-copy" streamable="true"/>

<xsl:template match="note">
  <!-- no action -->
</xsl:template>

</xsl:stylesheet>

6.8.46.7.4 Built-in Templates: Shallow Copy All

Changes in 4.0  

  1. The new value on-no-match="shallow-copy-all" is designed for processing trees of maps and arrays, such as arise from parsing JSON.  [Issue 570 ]

This processing mode is introduced in XSLT 4.0 as a variant of shallow-copy to enable recursive descent processing of trees involving maps and arrays, such as might result from parsing JSON input.

For all items other than maps and arrays, the effect of shallow-copy-all is exactly the same as shallow-copy.

For arrays, the processing is as follows. A new result array is created, and its content is populated by decomposing the input array to a sequence of value records using the function array:members. Each of these value records is processed by a call on xsl:apply-templates (using the current mode, and passing on the values of all template parameters); the result of the called template is expected to be a value record.

That is, the template rule is equivalent to the following, except that this does not show the propagation of template parameters:

If an entire tree is processed using the built-in rules, the result will be unchanged from the original. The purpose is to allow the processing of selected values within the tree to be overridden by explicit user-written template rules. See ??? for advice on writing overriding template rules for this mode of processing.

<xsl:array use="?value">
  <xsl:apply-templates select="array:members(.)" mode="#current"/>
</xsl:array>
6.7.4.1 Shallow Copy All: Processing Arrays

The default processing for an array constructs a new array with the same number of members as the original, each member being constructed by applying templates to the existing value.

The template rule is equivalent to the following, except that this does not show the propagation of template parameters:

<xsl:template match="type(array(*))">
   <xsl:array>
     <xsl:for-each select="array:members(.)">
        <xsl:array-member>
          <xsl:apply-templates select="?value" mode="#current"/>
        </xsl:array-member>
     </xsl:for-each>   
   </xsl:array>
</xsl:template>

Note:

Because the xsl:apply-templates instruction selects items that are labeled with the same root property as the context item, they are not relabeled, and therefore retain the ability to access their parents and ancestors within the overall processing.

Note:

A value record is a single-entry map: it has a single key-value pair with the key "value", the corresponding value being a member of the original array. The default processing for a value record, unless specified otherwise, is to apply templates to the value, as indicated by the rules that follow.

6.7.4.2 Shallow Copy All: Processing Maps

The default processing for a map constructs a new map with the same keys as the original; the value associated with each key is obtained by applying templates to the original value.

The template rule is equivalent to the following, except that this does not show the propagation of template parameters:

<xsl:template match="type(map(*))">
   <xsl:map>
      <xsl:for-each select="map:pairs(.)">
         <xsl:map:entry key="?key">
           <xsl:apply-templates select="?value"/>
         </xsl:map-entry>   
      </xsl:for-each>   
   </xsl:map>
</xsl:template>

Note:

Because the xsl:apply-templates instruction selects items that are labeled with the same root property as the context item, they are not relabeled, and therefore retain the ability to access their parents and ancestors within the overall processing.

For maps, the processing is as follows:

  • If the map contains two or more entries, then a new result map is created, and its content is populated by decomposing the input map using the function map:entries to produce a sequence of single-entry maps (each containing one key and one value), and then applying templates to this sequence, using the current mode, and passing on the values of all template parameters.

  • If the map contains a single entry { K : V0 }, then a new single entry map { K: V1 } is constructed in which V1 is the result of applying templates to V0 (using the current mode, and passing on the values of all template parameters).

    Note:

    This rule has the effect that if the input is a value record, the output will also be a value record.

  • If the map is empty, the result is an empty map.

In the first case, the template rule is equivalent to the following, except that this does not show the propagation of template parameters:

<xsl:map>
  <xsl:apply-templates select="map:entries(.)" mode="#current"/>
</xsl:map>

In the second case, the template rule is equivalent to the following, except that this does not show the propagation of template parameters:

<xsl:map-entry key="map:keys(.)">
  <xsl:apply-templates select="map:items(.)" mode="#current"/>
</xsl:map-entry>

The reason there is a special rule for maps with one entry is to ensure that the process terminates.

The overall effect is best understood with an example.

Example: Modified Identity Transformation of a JSON Document

The following stylesheet transforms a supplied JSON document by deleting all properties named "Note", appearing at any level:

6.7.4.3 Shallow Copy All: Examples
Example: Transforming Individual Map Entries

Many useful transformations can be achieved by overriding the processing of map entries that have a specific known key. Keys can be matched using label patterns: see 5.4.2.5 Label Patterns. For example:

<xsl:template match="?surname">
  <xsl:select>uppercase(.)</xsl:select>
</xsl:template>

<xsl:template match="?date-of-birth">
  <xsl:select>format-date(xs:date(.), '[D1] [MNn] [Y0001]')</xsl:select>
</xsl:template>

This approach does not work well, however, if the value associated with a key contains multiple items, or if it is empty. Subsequent examples in this section illustrate ways of handling this.

 

<xsl:stylesheet version="3.0"
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
				  
<xsl:mode on-no-match="shallow-copy-all"/>

<xsl:template match="record(Note)">
  <!-- no action -->
</xsl:template>

</xsl:stylesheet>
Example: Deleting Unwanted Entries from Maps

If any map is to be replaced by a map with a different set of keys, it is necessary to write an explicit template rule that matches the map.

For example, to delete "Note" entries from any map in which they appear, the following stylesheet might be used:

xsl:stylesheet version="3.0"
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
     default-mode="delete-notes">
				  
  <xsl:mode name="delete-notes" 
            on-no-match="shallow-copy-all">

    <xsl:template match="record(Note, *)">
      <xsl:apply-templates select="map:remove(., 'Note')"/>  
    </xsl:template>
    
  </xsl:mode>

</xsl:stylesheet>

The way this works is:

  • By default, all maps and arrays are processed using the built-in template rule, which copies them unchanged.

  • A map containing an entry with the key "Note" matches the pattern record(Note, *) and is therefore processed using a template rule that removes the "Note" entry and applies templates recursively to the map that results.

Note that the xsl:apply-templates instruction here is processing a map (the result of the map:remove operation) that is not labeled as belonging to the original processing tree, and it will therefore be labeled as part of a new tree with a different processing root. This can be avoided by instead writing:

<xsl:template match="record(Note, *)">
   <xsl:map>
      <xsl:for-each select="map:pair(.)[not(?key = 'Note')]">
        <xsl:map-entry key="?key">
          <xsl:apply-templates select="?value"/>
        </xsl:map-entry>
      </xsl:for-each>
   </xsl:map>
</xsl:template>

This can also be expressed as:

<xsl:template match="record(Note, *)">
   <xsl:select>
     map:build(map:pairs(.)[not(?key = 'Note')], 
               fn{?key},
               fn{apply-templates(?value)})
   </xsl:select>
</xsl:template>

The essential difference with these examples is that they apply templates to values that were present in the original processing tree, not to a newly constructed map.

Consider the following JSON input, converted to an array of maps by calling the function parse-json:

 

[
  { "Title": "Computer Architecture",
    "Authors": [ "Enid Blyton", { "Note": "possibly misattributed" } ],
    "Category": "Computers",
    "Price": 42.60
  },
  { "Title": "Steppenwolf",
    "Authors": [ "Hermann Hesse" ],
    "Category": "Fiction",
    "Price": 12.00,
    "Note": "out of print"
  },
  { "Title": "How to Explore Outer Space with Binoculars",
    "Authors": [ "Bruce Betts", "Erica Colon" ],
    "Category": "Science",
    "Price": 10.40
  }
]
Example: Processing non-Singleton Values

The default processing rules apply templates to individual items within the value of a map entry or the value of an array member. This creates a challenge when such a value is a sequence of more than one item, and needs to be processed as a group. This example illustrates such a case.

Consider the map:

{  "type": "cupboard",
   "material": "oak",
   "dimensions": (12.5, 6.2, 8.3)
}

where the requirement is to turn this into:

{  "type": "cupboard",
   "material": "oak",
   "dimensions": {'height': 12.5, 'width': 6.2, 'depth': 8.3}
}

A template rule written with match="?dimensions" will match each of the three decimal values individually, giving no opportunity to construct a single map to contain all three.

A solution to this is to override the processing of the containing map. For example:

<xsl:template match="record(type, material, dimensions, *)">
  <xsl:select>
    map:put(., 
       'dimensions', {'height': ?dimensions[1], 
                      'width': ?dimensions[2], 
                      'depth': ?dimensions[3]})
  </xsl:select/>
</xsl:template>

Alternatively, if other entries in the map also need to be transformed, it is possible is to process all the map entries using template rules that match key-value pairs. For example:

<xsl:template match="record(type, material, dimensions, *)">
  <xsl:map>
    <xsl:apply-templates select="map:entries(.)" 
                         mode="furniture-properties"/>
  </xsl:map>  
</xsl:template>

<xsl:mode name="furniture-properties" 
          on-no-match="shallow-copy-all">
          
   <xsl:template match="?dimensions'">
       <xsl:record height="?value[1]" 
                   width="?value[2]" 
                   depth="?value[3]"/>
   </xsl:template>
   
   <xsl:template match=".">
       <xsl:apply-templates select="." mode="#unnamed"/>
   </xsl:template>
   
</xsl:mode>

In this example the mode furniture-properties is only used to process singleton maps (maps containing a single entry). If the key in the singleton map is "dimensions", then the sequence of three decimals is replaced by a map with three entries; in all other cases, processing is delegated back to the original unnamed mode.

Note that the switching between two different modes does not affect the labels on any values in the tree. When the context item for a call on xsl:apply-templates is labeled with a particular navigation root, and any items selected by the xsl:apply-templates instruction will be labeled with the same navigation root, even if the processing is in a different mode.

The logic proceeds as follows:

  1. The outermost array is processed by applying templates to a sequence of value records, the first being in the form:

    { "value": map: { "Title": ..., "Author": ..., ... }

    The result of applying templates to these value records is expected to comprise a new sequence of value records, which is used to construct the final output array.

  2. Each of the value records is processed using the rule for single-entry maps. This rule produces a new value record by applying templates to the value, that is, to a map of the form map: { "Title": ..., "Author": ..., ... } representing a book.

  3. Each of these books, being represented by a map with more than two entries, is processed by a template rule that splits the map into its multiple entries, each represented as a singleton map (a map with one key and one value). One of these single-entry maps, for example, would be {"Title": "Steppenwolf"}.

  4. The default processing for a single-entry map of the form { "Title": "Steppenwolf" } is to return the value unchanged. This is achieved by applying templates to the string "Steppenwolf"; the default template rule for strings returns the string unchanged.

  5. When a single-entry map in the form { "Note": "out of print" } is encountered, no output is produced, meaning that entry in the parent map is effectively dropped. This is because there is an explicit template rule with match="record(Note)" that matches such single-entry maps.

  6. When a single-entry map in the form "Authors": [ "Bruce Betts", "Erica Colon" ] is encountered, a new single-entry map is produced; it has the same key ("Authors"), and a value obtained by applying templates to the array [ "Bruce Betts", "Erica Colon" ]. The default processing for an array, in which none of the constituents are matched by explicit template rules, ends up delivering a copy of the array.

  7. When the single-entry map "Authors": [ "Enid Blyton", { "Note": "possibly misattributed" } ] is encountered, the recursive processing results in templates being applied to the map { "Note": "possibly misattributed" }. This matches the template rule having match="record(Note)", which returns no output, so the entry is effectively deleted.

    Note:

    The map entry is deleted, but the map itself remains, so the value becomes "Authors": [ "Enid Blyton", map: {} ].

6.8.56.7.5 Built-in Templates: Deep Skip

The effect of processing a tree using a mode that specifies on-no-match="deep-skip" is that where no explicit template rule is specified for an element, that element and all its descendants are ignored, and are not copied to the result tree.

The effect of choosing on-no-match="deep-skip" is as follows:

  • The built-in rule for document nodes is equivalent to calling xsl:apply-templates with no select attribute, and with the mode attribute set to #current. If the built-in rule was invoked with parameters, those parameters are passed on in the implicit xsl:apply-templates instruction.

    In the case where there are no parameters, this is equivalent to the following rule:

    <xsl:template match="document-node()" mode="M">
      <xsl:apply-templates mode="#current"/>
    </xsl:template>
  • The built-in rule for all items other than document nodes (that is, for all other kinds of node, as well as atomic items and functions, including maps and and arrays) is to do nothing, that is, to return an empty sequence (without applying templates to any children or ancestors).

    This is equivalent to the following rule:

    <xsl:template match="." mode="M"/>

6.8.66.7.6 Built-in Templates: Shallow Skip

The effect of processing a tree using a mode that specifies on-no-match="shallow-skip" is to drop both the textual content and the markup from the result document, except where there is an explicit user-written template rule that dictates otherwise.

The built-in rule for document nodes and element nodes applies templates (in the current mode) first to the node’s attributes and then to its children. If the built-in rule was invoked with parameters, those parameters are passed on in the implicit xsl:apply-templates instructions.

In the case where there are no parameters, this is equivalent to the following rule:

<xsl:template match="document-node()|element()" mode="M">
  <xsl:apply-templates select="@*" mode="#current"/>
  <xsl:apply-templates mode="#current"/>
</xsl:template>

The built-in template rule for all other kinds of node, and for atomic items and functions (including maps, but not arrays) is empty: that is, when the item is matched, the built-in template rule returns an empty sequence.

This is equivalent to the following rule:

<xsl:template match="." mode="M"/>

The built-in template rule for arrays (see 22 Arrays) is to apply templates to the members of the array. It is equivalent to invoking xsl:apply-templates with the select attribute set to ?* (which selects the members of the array), and with the mode attribute set to #current. If the built-in rule was invoked with parameters, those parameters are passed on in the implicit xsl:apply-templates instruction.

This is equivalent to the following in the case where there are no parameters:

<xsl:template match=".[. instance of array(*)]" mode="M">
  <xsl:apply-templates mode="#current" select="?*"/>
</xsl:template>

6.8.76.7.7 Built-in Templates: Fail

The effect of choosing on-no-match="fail" for a mode is that every item selected in an xsl:apply-templates instruction must be matched by an explicit user-written template rule.

The built-in template rule is effectively:

<xsl:template match="." mode="M">
  <xsl:message terminate="yes" error-code="err:XTDE0555"/>
</xsl:template>

with an implementation-dependent message body.

[ERR XTDE0555] It is a dynamic error if xsl:apply-templates, xsl:apply-imports or xsl:next-match is used to process an item using a mode whose declaration specifies on-no-match="fail" when there is no template rule in the stylesheet whose match pattern matches that item.

6.96.8 Overriding Template Rules

Changes in 4.0  

  1. The xsl:apply-imports and xsl:next-match instructions automatically pass supplied parameters to the overridden template rule.   [Issue 1861 ]

<!-- Category: instruction -->
<xsl:apply-imports>
  <!-- Content: xsl:with-param* -->
</xsl:apply-imports>

<!-- Category: instruction -->
<xsl:next-match>
  <!-- Content: (xsl:with-param | xsl:fallback)* -->
</xsl:next-match>

A template rule that is being used to override another template rule (see 6.56.4 Conflict Resolution for Template Rules) can use the xsl:apply-imports or xsl:next-match instruction to invoke the overridden template rule. The xsl:apply-imports instruction only considers template rules in imported stylesheet modules; the xsl:next-match instruction considers all template rules that have not already been used. Both instructions will invoke the built-in template rule for the context item (see 6.86.7 Built-in Template Rules) if no other template rule is found.

[Definition: At any point in the processing of a stylesheet, there may be a current template rule. Whenever a template rule is chosen as a result of evaluating xsl:apply-templates, xsl:apply-imports, or xsl:next-match, the template rule becomes the current template rule for the evaluation of the rule’s sequence constructor.]

The current template rule is cleared (becomes absent) by any instruction that evaluates an operand with changed focus. It is therefore cleared when evaluating instructions contained within:

Note:

The current template rule is not affected by invoking named attribute sets (see 10.2 Named Attribute Sets), or named templates (see 10.1 Named Templates) unless <xsl:context-item use="absent"/> is specified. While evaluating a global variable or the default value of a stylesheet parameter (see 9.5 Global Variables and Parameters) the current template rule is absent.

These rules ensure that when xsl:apply-imports or xsl:next-match is called, the context item is the same as when the current template rule was invoked.

Both xsl:apply-imports and xsl:next-match search for a template rule that matches the context item, and that is applicable to the current mode (see 6.76.6 Modes). In choosing a template rule, they use the usual criteria such as the priority and import precedence of the template rules, but they consider as candidates only a subset of the template rules in the stylesheet. This subset differs between the two instructions:

If no matching template rule is found, both xsl:apply-imports and xsl:next-match cause the built-in template rule for the mode to be invoked.

If multiple matching template rules with the same explicit or implicit priority are found, both xsl:apply-imports and xsl:next-match respect the on-multiple-match and warning-on-multiple-match attributes of the mode declaration.

Note:

If is entirely possible for xsl:apply-templates to identify a template rule unambiguously, and for xsl:apply-imports or xsl:next-match then to fail because there is no unambiguous second-choice template rule.

If a matching template rule R is found, then the result of the xsl:next-match or xsl:apply-imports instruction is the result of invoking R. The parameters that are passed to R are as follows:

Note:

The implicit passing of non-tunnel parameters is new in XSLT 4.0, and happens only if [xsl:]version is set to 4.0 (or greater) on the instruction, or on some ancestor element in the stylesheet. There may be cases where this change introduces a backward incompatibility: specifically, if the invoked template rule declares a default value for an optional parameter, it will now take the implicitly passed value rather than the default value. The 3.0 behavior can be therefore be retained by setting version="3.0" on the xsl:next-match or xsl:apply-imports instruction.

The template rule R is evaluated with the same focus as the xsl:next-match or xsl:apply-imports instruction. The current template rule changes to be R. The current mode does not change.

Note:

In the case where the current template rule T is declared within an xsl:override element in a using package P, while the selected rule R is declared within a different package Q, and where the current mode is MP (mode M in package P), the effect is that the current mode for evaluation of R remains MP rather than reverting to its corresponding mode MQ (mode M in package Q). If R contains an xsl:apply-templates instruction that uses mode="#current", then the set of template rules considered by this instruction will therefore include any overriding template rules declared in P as well as the original rules declared in Q.

If no matching template rule is found that satisfies these criteria, the built-in template rule for the context item is used (see 6.86.7 Built-in Template Rules).

[ERR XTDE0560] It is a dynamic error if xsl:apply-imports or xsl:next-match is evaluated when the current template rule is absent.

Example: Using xsl:apply-imports

For example, suppose the stylesheet doc.xsl contains a template rule for example elements:

<xsl:template match="example">
  <pre><xsl:apply-templates/></pre>
</xsl:template>

Another stylesheet could import doc.xsl and modify the treatment of example elements as follows:

<xsl:import href="doc.xsl"/>

<xsl:template match="example">
  <div style="border: solid red">
     <xsl:apply-imports/>
  </div>
</xsl:template>

The combined effect would be to transform an example into an element of the form:

<div style="border: solid red"><pre>...</pre></div>

An xsl:fallback instruction appearing as a child of an xsl:next-match instruction is ignored by an XSLT 2.0, 3.0, or 4.0 processor, but can be used to define fallback behavior when the stylesheet is processed by an XSLT 1.0 processor with forwards compatible behavior.

Example: Using xsl:next-match

This example shows how an input element such as:

<phrase upper-case="true" italic="true" bold="false" underscore="true">Hannover</phrase>

might be transformed into:

<italic><underscore>HANNOVER</underscore></italic>

The following template rules achieve the required effect:

<xsl:template match="phrase" priority="10">
  <xsl:next-match>
     <xsl:with-param name="upper-case" select="xs:boolean(@upper-case)"/>
  </xsl:next-match>
</xsl:template>  

<xsl:template match="phrase[xs:boolean(@italic)]" priority="8">
  <italic>
    <xsl:next-match/>
  </italic>
</xsl:template>

<xsl:template match="phrase[xs:boolean(@bold)]" priority="6">
  <bold>
    <xsl:next-match/>
  </bold>
</xsl:template>

<xsl:template match="phrase[xs:boolean(@underscore)]" priority="4">
  <underscore>
    <xsl:next-match/>
  </underscore>
</xsl:template>

<xsl:template match="phrase" priority="2">
  <xsl:param name="upper-case" as="xs:boolean?"/>
  <xsl:if test="$upper-case" then="upper-case(.)" else="string(.)"/>
</xsl:template>

Note how the $upper-case parameter is passed implicitly through the chain of template rules.

6.106.9 Passing Parameters to Template Rules

A template rule may have parameters. The parameters are declared in the body of the template using xsl:param elements, as described in 9.2 Parameters.

Values for these parameters may be supplied in the calling xsl:apply-templates, xsl:apply-imports, or xsl:next-match instruction by means of xsl:with-param elements appearing as children of the calling instruction. The expanded QName represented by the name attribute of the xsl:with-param element must match the expanded QName represented by the name attribute of the corresponding xsl:param element.

It is not an error for these instructions to supply a parameter that does not match any parameter declared in the template rule that is invoked; unneeded parameter values are simply ignored.

A parameter may be declared as a tunnel parameter by specifying tunnel="yes" in the xsl:param declaration; in this case the caller must supply the value as a tunnel parameter by specifying tunnel="yes" in the corresponding xsl:with-param element. Tunnel parameters differ from ordinary template parameters in that they are passed transparently through multiple template invocations. They are fully described in 10.1.6 Tunnel Parameters.

9 Variables and Parameters

[Definition: The two elements xsl:variable and xsl:param are referred to as variable-binding elements.]

[Definition: The xsl:variable element declares a variable, which may be a global variable or a local variable.]

[Definition: The xsl:param element declares a parameter, which may be a stylesheet parameter, a template parameter, a function parameter, or an xsl:iterate parameter. A parameter is a variable with the additional property that its value can be set by the caller.]

[Definition: A variable is a binding between a name and a value. The value of a variable is any sequence (of nodes, atomic items, and/or function items), as defined in [XDM 3.0].]

9.4 Creating Implicit Document Nodes

A document node is created implicitly when evaluating an xsl:variable, xsl:param, or xsl:with-param element that has non-empty content and that has no as attribute. The value of the variable is this newly constructed document node. The content of the document node is formed from the result of evaluating the sequence constructor contained within the variable-binding element, as described in 5.8.1 Constructing Complex Content.

Note:

The construct:

<xsl:variable name="tree">
  <a/>
</xsl:variable>

can be regarded as a shorthand for:

<xsl:variable name="tree" as="document-node()">
  <xsl:document validation="preserve">
    <a/>
  </xsl:document>  
</xsl:variable>

The base URI of the document node is taken from the base URI of the variable binding element in the stylesheet. (See Section 5.2 base-uri Accessor DM30 in [XDM 3.0])

No document-level validation takes place (which means, for example, that there is no checking that ID values are unique). However, type annotations on nodes within the new tree are copied unchanged.

Note:

The base URI of other nodes in the tree is determined by the rules for constructing complex content (see 5.8.1 Constructing Complex Content). The effect of these rules is that the base URI of a node in the temporary tree is determined as if all the nodes in the temporary tree came from a single entity whose URI was the base URI of the variable-binding element. Thus, the base URI of the document node will be equal to the base URI of the variable-binding element, while an xml:base attribute within the temporary tree will change the base URI for its parent element and that element’s descendants, just as it would within a document constructed by parsing.

The document-uri and unparsed-entities properties of the new document node are set to empty.

A temporary tree is available for processing in exactly the same way as any source document. For example, its nodes are accessible using path expressions, and they can be processed using instructions such as xsl:apply-templates and xsl:for-each. Also, the key and id functions can be used to find nodes within a temporary tree, by supplying the document node at the root of the tree as an argument to the function or by making it the context node.

Example: Two-Phase Transformation

The following stylesheet uses a temporary tree as the intermediate result of a two-phase transformation, using different modes for the two phases (see 6.76.6 Modes). Typically, the template rules in module phase1.xsl will be declared with mode="phase1", while those in module phase2.xsl will be declared with mode="phase2":

<xsl:stylesheet
  version="3.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:import href="phase1.xsl"/>
<xsl:import href="phase2.xsl"/>

<xsl:variable name="intermediate">
  <xsl:apply-templates select="/" mode="phase1"/>
</xsl:variable>

<xsl:template match="/">
  <xsl:apply-templates select="$intermediate" mode="phase2"/>
</xsl:template>

</xsl:stylesheet>

Note:

The algorithm for matching nodes against template rules is exactly the same regardless which tree the nodes come from. If different template rules are to be used when processing different trees, then unless nodes from different trees can be distinguished by means of patterns, it is a good idea to use modes to ensure that each tree is processed using the appropriate set of template rules.

10 Callable Components

This section describes three constructs that can be used to provide subroutine-like functionality that can be invoked from anywhere in the stylesheet: named templates (see 10.1 Named Templates), named attribute sets (see 10.2 Named Attribute Sets), and stylesheet functions (see 10.3 Stylesheet Functions).

[Definition: The following constructs are classified as invocation constructs: the instructions xsl:call-template, xsl:apply-templates, xsl:apply-imports, and xsl:next-match; XPath function calls that bind to stylesheet functions; XPath dynamic function calls; the functions accumulator-before and accumulator-after; the [xsl:]use-attribute-sets attribute. These all have the characteristic that they can cause evaluation of constructs that are not lexically contained within the calling construct.]

10.1 Named Templates

10.1.6 Tunnel Parameters

[Definition: A parameter passed to a template may be defined as a tunnel parameter. Tunnel parameters have the property that they are automatically passed on by the called template to any further templates that it calls, and so on recursively.] Tunnel parameters thus allow values to be set that are accessible during an entire phase of stylesheet processing, without the need for each template that is used during that phase to be aware of the parameter.

Note:

Tunnel parameters are conceptually similar to the dynamically scoped variables found in some functional programming languages (for example, early versions of LISP), where evaluating a variable reference involves searching down the dynamic call stack for a matching variable name. There are two main use cases for the feature:

  1. They provide a way to supply context information that might be needed by many templates (for example, the fact that the output is to be localized for a particular language), but which cannot be placed in a global variable because it might vary from one phase of processing to another. Passing such information using conventional parameters is error-prone, because a single xsl:apply-templates or xsl:call-template instruction that neglects to pass the information on will lead to failures that are difficult to diagnose.

    This style of processing is even more useful when handling JSON input, because with maps and arrays, there is no ancestor axis to examine properties of nodes further up the tree; with a recursive descent of the tree, all context information needs to be passed down explicitly. One way of handling this is for each level of processing in the tree to bind a tunnel parameter to the map or array encountered at that level, which then becomes available to all template rules processing data further down the tree.

  2. They are particularly useful when writing a customization layer for an existing stylesheet. For example, if you want to override a template rule that displays chemical formulae, you might want the new rule to be parameterized so you can apply the house-style of a particular scientific journal. Tunnel parameters allow you to pass this information to the overriding template rule without requiring modifications to all the intermediate template rules. Again, a global variable could be used, but only if the same house-style is to be used for all chemical formulae processed during a single transformation.

A tunnel parameter is created by using an xsl:with-param element that specifies tunnel="yes". A template that requires access to the value of a tunnel parameter must declare it using an xsl:param element that also specifies tunnel="yes".

On any template call using an xsl:apply-templates, xsl:call-template, xsl:apply-imports or xsl:next-match instruction, a set of tunnel parameters is passed from the calling template to the called template. This set consists of any parameters explicitly created using <xsl:with-param tunnel="yes">, overlaid on a base set of tunnel parameters. If the xsl:apply-templates, xsl:call-template, xsl:apply-imports or xsl:next-match instruction has an xsl:template declaration as an ancestor element in the stylesheet, then the base set consists of the tunnel parameters that were passed to that template; otherwise (for example, if the instruction is within a global variable declaration, an attribute set declaration, or a stylesheet function), the base set is empty. If a parameter created using <xsl:with-param tunnel="yes"> has the same expanded QName as a parameter in the base set, then the parameter created using xsl:with-param overrides the parameter in the base set; otherwise, the parameter created using xsl:with-param is added to the base set.

When a template specifies <xsl:param tunnel="yes">, this declares the intention to make use of a tunnel parameter; it does not remove the parameter from the base set of tunnel parameters that is passed on to any templates called by this template. [XSLT 3.0 Erratum E23, bug 30240].

Two sibling xsl:with-param elements must have distinct parameter names, even if one is a tunnel parameter and the other is not. Equally, two sibling xsl:param elements representing template parametersmust have distinct parameter names, even if one is a tunnel parameter and the other is not. However, the tunnel parameters that are implicitly passed in a template call may have names that duplicate the names of non-tunnel parameters that are explicitly passed on the same call.

Tunnel parameters are not passed in calls to stylesheet functions.

All other options of xsl:with-param and xsl:param are available with tunnel parameters just as with non-tunnel parameters. For example, parameters may be declared as mandatory or optional, a default value may be specified, and a required type may be specified. If any conversion is required from the supplied value of a tunnel parameter to the required type specified in xsl:param, then the converted value is used within the receiving template, but the value that is passed on in any further template calls is the original supplied value before conversion. Equally, any default value is local to the template: specifying a default value for a tunnel parameter does not change the set of tunnel parameters that is passed on in further template calls.

Tunnel parameters are passed unchanged through a built-in template rule (see 6.86.7 Built-in Template Rules).

If a tunnel parameter is declared in an xsl:param element with the attribute tunnel="yes", and if the parameter is explicitly or implicitly mandatory, then a dynamic error occurs [see ERR XTDE0700] if the set of tunnel parameters passed to the template does not include a parameter with a matching expanded QName.

Example: Using Tunnel Parameters

Suppose that the equations in a scientific paper are to be sequentially numbered, but that the format of the number depends on the context in which the equations appear. It is possible to reflect this using a rule of the form:

<xsl:template match="equation">
  <xsl:param name="equation-format" select="'(1)'" tunnel="yes"/>
  <xsl:number level="any" format="{ $equation-format }"/>
</xsl:template>

At any level of processing above this level, it is possible to determine how the equations will be numbered, for example:

<xsl:template match="appendix">
  ...
  <xsl:apply-templates>
    <xsl:with-param name="equation-format" select="'[i]'" tunnel="yes"/>
  </xsl:apply-templates>
  ...
</xsl:template>

The parameter value is passed transparently through all the intermediate layers of template rules until it reaches the rule with match="equation". The effect is similar to using a global variable, except that the parameter can take different values during different phases of the transformation.

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.9 Examples of Streamability Analysis

The examples in this section are intended to illustrate how the streamability rules are applied “top down” to establish whether template rules are guaranteed streamable.

Example: A recursive-descent template rule

Consider the following template rule, where mode s is defined with streamable="yes":

<xsl:template match="para" mode="s">
  <div class="para">
    <xsl:apply-templates mode="s"/>
  </div>
</xsl:template>

The processor is required to establish that this template meets the streamability rules. Specifically, as stated in 6.7.76.6.6 Streamable Templates, it must satisfy three conditions:

  1. The match pattern must be motionless.

  2. The body of the template rule must be grounded.

  3. The initializers of any template parameters must be motionless.

The third condition is satisfied trivially because there are no parameters.

The first rule depends on the rules for assessing patterns, which are given in 19.8.10 Classifying Patterns. This pattern is motionless because (a) it does not contain a RootedPath, and (b) it contains no predicates.

So it remains to determine that the body of the template is grounded. The proof of this is as follows:

  1. The sequence constructor forming the body of the template is assessed according to the rules in 19.8.3 Classifying Sequence Constructors, which tell us that there is a single operand (the <div>literal result element) which has operand usageU = transmission.

  2. The assessment of the sequence constructor uses the general streamability rules. These rules require us to determine the type T, sweep S, posture P, and usage U of each operand. We have already established that there is a single operand, with U = transmission. Section 19.1 Determining the Static Type of a Construct tells us that for all instructions, we can take T = U{*}. The postureP and sweepS of the literal result element are established as follows:

    1. The rules for literal result elements (specifically the <div> element) are given in 19.8.4.1 Streamability of Literal Result Elements. This particular literal result element has only one operand (its contained sequence constructor), with operand usageU = absorption.

    2. The general streamability rules again apply. Again the static typeT of the operand is U{*}, and we need to determine the postureP and sweepS.

    3. To determine the posture and sweep of this sequence constructor (the one that contains the xsl:apply-templates instruction) we refer again to the general streamability rules.

      1. The sequence constructor has a single operand (the xsl:apply-templates instruction); again U = transmission, T = U{*}.

      2. The postureP and sweepS of the xsl:apply-templates instruction are established as follows:

        1. The rules that apply are in 19.8.4.5 Streamability of xsl:apply-templates.

        2. Rule 1 does not apply because the select expression (which defaults to child::node()) is not grounded. This is a consequence of the rules in 19.8.8.9 Streamability of Axis Steps, specifically:

          1. The context posture of the axis step is established by the template rule as a whole, as striding.

          2. Therefore rules 1 and 2 do not apply.

          3. The statically inferred context item type is derived from the match pattern (match="para"). This gives a type of U{element()}. The child axis for element nodes is not necessarily empty, so rule 3 does not apply.

          4. Rule 4 does not apply because there are no predicates.

          5. So the posture and sweep of the axis step child::node() are given by the table in rule 5. The entry for (context posture = striding, axis = child) gives a posture of striding and a sweep of consuming.

          6. So the select expression is not grounded. (The same result can be reached intuitively: an expression that selects streamed nodes will never be grounded.)

        3. Rule 2 does not apply because there is no xsl:sort element.

        4. Rule 3 does not apply because the mode is declared with streamable="yes".

        5. So the postureP and sweepS of the xsl:apply-templates instruction are established by the general streamability rules, as follows:

          1. There is a single operand, the implicit select="child::node()" expression, with usage U = absorption.

          2. We have already established that for this operand, the posture P = striding and the sweepS = consuming.

          3. By the rules in 19.1 Determining the Static Type of a Construct, the type T of the select expression is node().

          4. In the general streamability rules, the adjusted sweep S′ for an operand with (P = striding, U = absorption) is consuming,

          5. Rule 2(d) then applies, so the xsl:apply-templates instruction is consuming and grounded.

      3. So the sequence constructor that contains the xsl:apply-templates instruction has one operand with U = transmission, T = item(), P = grounded, S = consuming. Rule 2(d) of the general streamability rules applies, so the sequence constructor itself has P = grounded, S = consuming.

    4. So the literal result element has one operand with U = absorption, T = item(), P = grounded, S = consuming. Rule 2(d) of the general streamability rules applies, so the literal result element has P = grounded, S = consuming.

  3. So the sequence constructor containing the literal result element has one operand with U = transmission, T = item(), P = grounded, S = consuming. Rule 2(d) of the general streamability rules applies, so this sequence constructor itself has P = grounded, S = consuming.

  4. So we have established that the sequence constructor forming the body of the template rule is grounded.

Therefore, since the other conditions are also satisfied, the template is guaranteed-streamable.

The analysis presented above could have been simplified by taking into account the fact that the streamability properties of a sequence constructor containing a single instruction are identical to the properties of that instruction. This simplification will be exploited in the next example.

 

Example: An aggregating template rule

Consider the following template rule, where mode s is defined with streamable="yes":

<xsl:template match="transactions[@currency='USD']" mode="s">
  <total><xsl:value-of select="sum(transaction/@value)"/></total>
</xsl:template>

Again, as stated in 6.7.76.6.6 Streamable Templates, it must satisfy three conditions:

  1. The match pattern must be motionless.

  2. The body of the template rule must be grounded.

  3. The initializers of any template parameters must be motionless.

The third condition is satisfied trivially because there are no parameters.

The first rule depends on the rules for assessing patterns, which are given in 19.8.10 Classifying Patterns. This pattern is motionless because (a) it is not a RootedPath, and (b) every predicate is motionless and non-positional. The analysis that proves the predicate is motionless and non-positional proceeds as follows:

  1. First establish that the expression @currency='USD' is motionless, as follows:

    1. The predicate is a general comparison (GeneralComp) which follows the general streamability rules.

    2. There are two operands: an AxisStep with a defaulted ForwardAxis, and a Literal. Both operand roles are absorption.

    3. The left-hand operand has type T = attribute(). Its posture and sweep are determined by the rules in 19.8.8.9 Streamability of Axis Steps. The context posture is striding, so the posture and sweep are determined by the entry in the table (rule 5) with context posture = striding, axis = attribute: that is, the result posture is striding and the sweep is motionless.

    4. The right-hand operand, being a literal, is grounded and motionless.

    5. In the general streamability rules, rule 2(e) applies, so the predicate is grounded and motionless

  2. Now establish that the expression @currency='USD' is non-positional, as follows:

    1. Rule 1 is satisfied: the predicate does not call position, last, or function-lookup.

    2. Rule 2 is satisfied: the expression @currency='USD' is non-numeric. The static type of the expression is determined using the rules in 19.1 Determining the Static Type of a Construct as U{xs:boolean}, and this has no intersection with U{xs:decimal, xs:double, xs:float}.

So both conditions in 19.8.10 Classifying Patterns are satisfied, and the pattern is therefore motionless.

It remains to show that the body of the template rule is grounded. The proof of this is as follows. Unlike the previous example, the analysis is shown in simplified form; in particular the two sequence constructors which each contain a single instruction are ignored, and replaced in the construct tree by their contained instruction.

  1. We need to show that the <total>literal result element is grounded.

  2. The rules that apply are in 19.8.4.1 Streamability of Literal Result Elements.

  3. These rules refer to the general streamability rules. There is one operand, the xsl:value-of child element, which has operand usageU = absorption, and type T = item().

  4. So we need to determine the posture and sweep of the xsl:value-of instruction.

    1. The rules are given in 19.8.4.42 Streamability of xsl:value-of.

    2. The general streamability rules apply. There is one operand, the expression sum(transaction/@value), which has operand usageU = absorption.

    3. The type T of this operand is the return type defined in the signature of the sum function, that is, xs:anyAtomicType.

    4. The postureP and sweepS are established as follows:

      1. The rules that apply to the call on sum are given in 19.8.9 Classifying Calls to Built-In Functions.

      2. The relevant proforma is fn:sum(A), indicating that the general streamability rules apply, and that there is a single operand with usage U = absorption.

      3. The type T of the operand transaction/@value is determined (by the rules in 19.1 Determining the Static Type of a Construct) as attribute().

      4. The postureP and sweepS of the operand transaction/@value are determined by the rules in 19.8.8.8 Streamability of Path Expressions, as follows:

        1. The expression is expanded to child::transaction/attribute::value.

        2. The posture and sweep of the left-hand operand child::transaction are determined by the rules in 19.8.8.9 Streamability of Axis Steps, as follows:

          1. The context posture is striding, because the focus-setting container is the template rule itself.

          2. The context item type is element(), based on the match type of the pattern match="transactions[@currency='USD']".

          3. Rules 1 and 2 do not apply because the context posture is striding.

          4. Rule 3 does not apply because the child axis applied to an element node is not necessarily empty.

          5. Rule 4 does not apply because there are no predicates.

          6. Rule 5 applies, and the table entry with context posture = striding, axis = child gives a result posture of striding and a sweep of consuming.

        3. The posture of the relative path expression child::transaction/attribute::value is therefore the posture of its right-hand operand attribute::value, assessed with a context posture of striding. This is determined by the rules in 19.8.8.9 Streamability of Axis Steps, as follows:

          1. The context posture, as we have seen, is striding.

          2. The context item type is element(), based on the type of the left-hand operand child::transaction.

          3. Rules 1 and 2 do not apply because the context posture is striding.

          4. Rule 3 does not apply because the attribute axis applied to an element node is not necessarily empty.

          5. Rule 4 does not apply because there are no predicates.

          6. Rule 5 applies, and the table entry with context posture = striding, axis = attribute gives a result posture of striding and a sweep of motionless.

        4. The posture of the relative path expression child::transaction/attribute::value is therefore striding.

        5. The sweep of the relative path expression child::transaction/attribute::value is the wider of the sweeps of its two operands, namely consuming and motionless. That is, it is consuming.

      5. So the first and only operand to the call on sum() has U = absorption, T = attribute(), P = climbing, and S = consuming

      6. Rule 1(b) of the general streamability rules computes the adjusted sweep S′. Rule 1(b)(iii)(A) applies, so the effective operand usageU′ is inspection. Rule 1(b)(iii)(A) then computes the adjusted sweep from the table entry for P = climbing, U′ = inspection; this shows S′ = S, that is, consuming.

      7. Rule 2(d) now applies, so the call on sum() is grounded and consuming.

    5. Since the xsl:value-of instruction has one operand with U = absorption, T = xs:anyAtomicType, P = grounded, and S = consuming, rule 2(d) again applies, and the xsl:value-of instruction is grounded and consuming.

  5. Since the literal result element has one operand with U = absorption, T = item(), P = grounded, and S = consuming, rule 2(d) again applies, and the literal result element is grounded and consuming.

  6. Therefore the body of the template rule is grounded, and since the other conditions are also satisfied, it is guaranteed-streamable.

 

Example: Streamed Grouping

Consider the following code, which is designed to process a transaction file containing transactions in chronological order, and output the total value of the transactions for each day.

<xsl:template name="go">
  <out>
    <xsl:source-document streamable="yes" href="transactions.xml">
      <xsl:for-each-group select="/account/transaction" 
                          group-adjacent="xs:date(@timestamp)">
         <total date="{current-grouping-key()}" value="{sum(current-group()/@value)}"/>
      </xsl:for-each-group>
    </xsl:source-document>
  </out>
</xsl:template>

The rules for xsl:source-document say that the instruction is guaranteed-streamable if the contained sequence constructor is grounded, and the task of streamability analysis is to prove that this is the case. As in the previous example, we will take a short-cut by making the assumption that a sequence constructor containing a single instruction can be replaced by that instruction in the construct tree.

So the task is to show that the xsl:for-each-group instruction is grounded, which we can do as follows:

  1. The relevant rules are to be found in 19.8.4.19 Streamability of xsl:for-each-group.

    Note:

    Rule numbers may be different in a version of the specification with change markings.

  2. Rule 1 applies only if the select expression is grounded. It is easy to see informally that this is not the case (an expression that returns streamed nodes is never grounded). More formally:

    1. The select expression is a path expression; the rules in 19.8.8.8 Streamability of Path Expressions apply.

    2. The expression is rewritten as ((root(.) treat as document-node())/child::account)/child::transaction

    3. The left-hand operand (root(.) treat as document-node())/child::account is also a path expression, so the rules in 19.8.8.8 Streamability of Path Expressions apply recursively:

      1. The left-hand operand root(.) treat as document-node() follows the rules for a TreatExpr in 19.8.8 Classifying Expressions; the proforma T treat as TYPE indicates that the general streamability rules apply with a single operand having usage transmission.

      2. This single operand root(.) follows the rules in 19.8.9.20 Streamability of the root Function. The item type of the operand . is the context item type, which is the type established by the xsl:source-document instruction, namely document-node(). Under these conditions root(.) is rewritten as ., so the posture is the context posture established by the xsl:source-document instruction, namely striding. The sweep is motionless.

      3. The posture and sweep of the expression root(.) treat as document-node() are the same as the posture and sweep of root(.), namely striding and motionless

      4. The right-hand operand child::account is governed by the rules in 19.8.8.9 Streamability of Axis Steps. The context posture is striding, and the axis is child, so the result posture is striding and the sweep is consuming.

      5. The posture of the path expression is the posture of the right-hand operand, that is striding, and its sweep is the wider sweep of the two operands, that is consuming

    4. Returning to the outer path expression, the posture of the right hand operand child::transaction is striding, and its sweep is consuming.

    5. So the posture of the select expression as a whole is the posture of the right hand operand, that is striding; and its sweep is the wider of the sweeps of the operands, which is consuming.

  3. Rule 2 does not apply: there is no group-by attribute.

  4. Rule 3 does not apply: there is a group-adjacent attribute, but it is motionless. The reasoning is as follows:

    1. The value is a call to the constructor function xs:date. The rules in 19.8.8.14 Streamability of Static Function Calls apply. There is a single operand, whose required type is atomic, so the operand usage is absorption.

    2. These rules refer to the general streamability rules, so we need to determine the context item type, posture, and sweep of the operand expression @timestamp. This is done as follows:

      1. The expression is an AxisStep, so the relevant rules are in 19.8.8.9 Streamability of Axis Steps.

      2. The context posture is the posture of the controlling operand of the focus-setting container, that is, is the select expression of the containing xsl:for-each-group instruction, which as established above is striding. The context item type is similarly the inferred type of the select expression, and is element().

      3. Rules 1 and 2 do not apply because the context posture is striding.

      4. Rule 3 does not apply because the attribute axis for an element node is not necessarily empty.

      5. Rule 4 does not apply because there is no predicate.

      6. So the sweep and posture of the expression @timestamp are given by the table in Rule 5 as striding and motionless.

    3. Returning to the general streamability rules for the expression xs:date(@timestamp), the operand @timestamp has U = absorption, T = attribute(), P = striding, S = motionless.

    4. Under Rule 1(b)(iii)(A), because T = attribute(), the operand usageU′ becomes inspection.

    5. Under Rule 1(b)(iii)(A), S′ = S = motionless.

    6. Under Rule 2(e), the expression xs:date(@timestamp) is grounded and motionless.

  5. Rule 4 (under xsl:for-each-group) does not apply, because there is no xsl:sort child.

  6. So Rule 5 applies. This relies on knowing the posture of the sequence constructor contained in the xsl:for-each-group instruction: that is, the posture of the totalliteral result element. This is calculated as follows:

    1. The rules that apply are in 19.8.4.1 Streamability of Literal Result Elements. The general streamability rules apply; there are two operands, the attribute value templates {current-grouping-key()} and {sum(current-group()/@value)}, and in each case the usage is absorption. We can simplify the analysis by observing that the empty sequence constructor contained in the literal result element can be ignored, since it is grounded and motionless.

    2. Consider first the operand {current-grouping-key()}.

      1. Section 19.8.7 Classifying Value Templates applies. This refers to the general streamability rules; there is a single operand, the expression current-grouping-key(), with usage absorption.

      2. Section 19.8.9.5 Streamability of the current-grouping-key Function applies. This establishes that the expression is grounded and motionless.

      3. It follows that the operand {current-grouping-key()} expression is also grounded and motionless.

    3. Now consider the operand {sum(current-group()/@value)}.

    4. Section 19.8.7 Classifying Value Templates applies. This refers to the general streamability rules; there is a single operand, the expression sum(current-group()/@value), with usage absorption.

    5. The rules for the sum function appear in 19.8.9 Classifying Calls to Built-In Functions. The proforma is given there as fn:sum(A), which means that the general streamability rules apply, and that the single operand current-group()/@value has usage absorption. So we need to establish the posture, sweep, and type of this expression, which we can do as follows:

      1. The expression is a RelativePathExpr, so section 19.8.8.8 Streamability of Path Expressions applies.

      2. The expression is expanded to current-group()/attribute::value.

      3. The posture and sweep of the left-hand operand current-group() are defined in 19.8.9.4 Streamability of the current-group Function. Since all the required conditions are satisfied, the posture of current-group() is the posture of the select expression, that is striding, and its sweep is the sweep of the select expression, that is consuming.

      4. The posture and sweep of the right hand operand @value are defined in 19.8.8.9 Streamability of Axis Steps. The context posture is the posture of the left-hand operand current-group(), namely striding; the table in Rule 5 applies, giving the result climbing and motionless

      5. The posture of the RelativePathExpr is the posture of the right hand operand, namely striding. The sweep of the RelativePathExpr is the wider of the sweeps of its operands, which is consuming

      6. The type of the expression current-group()/@value is determined using the rules in 19.1 Determining the Static Type of a Construct as attribute().

    6. So the sum function has a single operand with U = absorption, P = striding, S = consuming, T = attribute().

    7. In the general streamability rules, Rule 1(b)(iii)(A) gives the adjusted usage as U′ = inspection, and Rule 1(b)(iii)(B) gives the adjusted sweep as S′ = S = consuming. Rule 2(d) gives the posture and sweep of the call to sum as grounded and consuming.

  7. So the literal result element has two operands, one of which is grounded and motionless, the other grounded and consuming. Rule 2(d) of the general streamability rules determines that the literal result element is grounded and consuming.

  8. So the content of the xsl:source-document instruction is grounded, which means that the instruction is guaranteed-streamable.

B Glossary (Non-Normative)

absent

A component of the context that has no value is said to be absent.

absorption

An operand usage of absorption indicates that the construct reads the subtree(s) rooted at a supplied node(s).

accumulator

An accumulator defines a series of values associated with the nodes of the tree. If an accumulator is applicable to a particular tree, then for each node in the tree, other than attribute and namespace nodes, there will be two values available, called the pre-descent and post-descent values. These two values are available via a pair of functions, accumulator-before and accumulator-after.

accumulator function

The functions accumulator-before and accumulator-after are referred to as the accumulator functions.

alias

A stylesheet can use the xsl:namespace-alias element to declare that a literal namespace URI is being used as an alias for a target namespace URI.

applicable

A template rule is applicable to one or more modes. The modes to which it is applicable are defined by the mode attribute of the xsl:template element. If the attribute is omitted, then the template rule is applicable to the default mode specified in the [xsl:]default-mode attribute of the innermost containing element that has such an attribute, which in turn defaults to the unnamed mode. If the mode attribute is present, then its value must be a non-empty whitespace-separated list of tokens, each of which defines a mode to which the template rule is applicable.

applicable static namespaces

The applicable static namespaces for an element in a stylesheet module are the fixed namespace bindings for the module if the root element of the module has a fixed-namespaces attribute, or the native namespace bindings of the element otherwise.

arity range

A function definition has an arity range, which defines the minimum and maximum number of arguments that must be supplied in a call to the function. The static context can contain multiple function definitions with the same name, provided that their arity ranges do not overlap.

atomize

The term atomization is defined in Section 2.5.3 AtomizationXP. It is a process that takes as input a sequence of items, and returns a sequence of atomic items, in which the nodes are replaced by their typed values as defined in [XDM 3.0]. Arrays (see 22 Arrays) are atomized by atomizing their members, recursively.

attribute set

An attribute set is defined as a set of xsl:attribute-set declarations in the same package that share the same expanded QName.

attribute set invocation

An attribute set invocation is a pseudo-instruction corresponding to a single EQName appearing within an [xsl:]use-attribute-sets attribute; the effect of the pseudo-instruction is to cause the referenced attribute set to be evaluated.

attribute value template

In an attribute that is designated as an attribute value template, such as an attribute of a literal result element, an expression can be used by surrounding the expression with curly brackets ({}), following the general rules for value templates

backwards compatible behavior

An element is processed with backwards compatible behavior if its effective version is less than 4.0.

base output URI

The base output URI is a URI to be used as the base URI when resolving a relative URI reference allocated to a final result tree. If the transformation generates more than one final result tree, then typically each one will be allocated a URI relative to this base URI.

basic XSLT processor

A basic XSLT processor is an XSLT processor that implements all the mandatory requirements of this specification with the exception of constructs explicitly associated with an optional feature.

character map

A character map allows a specific character appearing in a text or attribute node in the final result tree to be substituted by a specified string of characters during serialization.

choice operand group

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

circularity

A circularity is said to exist if a construct such as a global variable, an attribute set, or a key, cannot be evaluated without reference to its own value. For example, if the expression or sequence constructor specifying the value of a global variableX references a global variable Y, then the value for Ymust be computed before the value of X. A circularity exists if it is impossible to do this for all global variable definitions.

climbing

Climbing: indicates that streamed nodes returned by the construct are reached by navigating the parent, ancestor[-or-self], attribute, and/or namespace axes from the node at the current streaming position.

coercion rules

When used in this specification without further qualification, the term coercion rules means the coercion rules defined in [XPath 4.0], applied with XPath 1.0 compatibility mode set to false.

collation

Facilities in XSLT 3.0 and XPath 3.0 that require strings to be ordered rely on the concept of a named collation. A collation is a set of rules that determine whether two strings are equal, and if not, which of them is to be sorted before the other.

combined merge key value

The ordered collection of merge key values computed for one item in a merge input sequence (one for each merge key component within the merge key specification) is referred to as a combined merge key value.

combined posture

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.

compatible

The signatures of two components are compatible if they present the same interface to the user of the component. The additional rules depend on the kind of component.

component

The term component is used to refer to any of the following: a stylesheet function, a named template, a mode, an accumulator, an attribute set, a key, global variable, or a mode.

construct

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.

consuming

A consuming construct is any construct deemed consuming by the rules in this section (19 Streamability).

containing package

A component declaration results in multiple components, one in the package in which the declaration appears, and potentially one in each package that uses the declaring package, directly or indirectly, subject to the visibility of the component. Each of these multiple components has the same declaring package, but each has a different containing package. For the original component, the declaring package and the containing package are the same; for a copy of a component made as a result of an xsl:use-package declaration, the declaring package will be the original package, and the containing package will be the package in which the xsl:use-package declaration appears.

context item

The context item is the item currently being processed. An item (see [XDM 3.0]) is either an atomic item (such as an integer, date, or string), a node, or a function item. It changes whenever instructions such as xsl:apply-templates and xsl:for-each are used to process a sequence of items; each item in such a sequence becomes the context item while that item is being processed.

context item type

For every expression, it is possible to establish by static analysis, information about the item type of the context item for evaluation of that expression. This is called the context item type of the expression.

context node

If the context item is a node (as distinct from an atomic item such as an integer), then it is also referred to as the context node. The context node is not an independent variable, it changes whenever the context item changes. When the context item is an atomic item or a function item, there is no context node.

context position

The context position is the position of the context item within the sequence of items currently being processed. It changes whenever the context item changes. When an instruction such as xsl:apply-templates or xsl:for-each is used to process a sequence of items, the first item in the sequence is processed with a context position of 1, the second item with a context position of 2, and so on.

context posture

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.

context size

The context size is the number of items in the sequence of items currently being processed. It changes whenever instructions such as xsl:apply-templates and xsl:for-each are used to process a sequence of items; during the processing of each one of those items, the context size is set to the count of the number of items in the sequence (or equivalently, the position of the last item in the sequence).

controlled operand

Within a focus-changing construct there are one or more operands that are evaluated with a focus determined by the controlling operand (or in some cases such as xsl:on-completion, with an absentfocus); these are referred to as controlled operands.

controlling operand

Within a focus-changing construct there is in many cases one operand whose value determines the focus for evaluating other operands; this is referred to as the controlling operand.

crawling

Crawling: typically indicates that streamed nodes returned by a construct are reached by navigating the descendant[-or-self] axis.

current captured groups

While the xsl:matching-substring instruction is active, a set of current captured groups is available, corresponding to the capturing subexpressions of the regular expression.

current group

The current group is the group itself, as a sequence of items

current grouping key

The current grouping key is a single atomic item, or in the case of a composite key, a sequence of atomic items, containing the grouping key of the items in the current group.

current merge group

The current merge group is a map. During evaluation of an xsl:merge instruction, as each group of items with equal combined merge key values is processed, the current merge group is set to a map whose keys are the names of the various merge sources, and whose associated values are the items from each merge source having the relevant composite merge key value.

current merge key

The current merge key is a an array, whose members are sequences of atomic items. There is one member in the array for each xsl:merge-key element in the merge key specification. During evaluation of an xsl:merge instruction, as each group of items with equal combined merge key values is processed, the current merge key is set to the combined merge key value that these items have in common.

current mode

At any point in the processing of a stylesheet, there is a current mode. When the transformation is initiated, the current mode is the initial mode, as described in 2.3 Initiating a Transformation. Whenever an xsl:apply-templates instruction is evaluated, the current mode becomes the mode selected by this instruction.

current output URI

The current output URI is the URI associated with the principal result or secondary result that is currently being written.

current template rule

At any point in the processing of a stylesheet, there may be a current template rule. Whenever a template rule is chosen as a result of evaluating xsl:apply-templates, xsl:apply-imports, or xsl:next-match, the template rule becomes the current template rule for the evaluation of the rule’s sequence constructor.

decimal format

All the xsl:decimal-format declarations in a package that share the same name are grouped into a named decimal format; those that have no name are grouped into a single unnamed decimal format.

declaration

Top-level elements fall into two categories: declarations, and user-defined data elements. Top-level elements whose names are in the XSLT namespace are declarations. Top-level elements in any other namespace are user-defined data elements (see 3.7.4 User-defined Data Elements)

declaration order

The declarations within a stylesheet level have a total ordering known as declaration order. The order of declarations within a stylesheet level is the same as the document order that would result if each stylesheet module were inserted textually in place of the xsl:include element that references it.

declared-streamable

The above constructs (template rules belonging to a mode declared with streamable="yes"; and xsl:source-document, xsl:attribute-set, xsl:function, xsl:merge-source, and xsl:accumulator elements specifying streamable="yes") are said to be declared-streamable.

declaring package

The declaring package of a component is the package that contains the declaration (or, in the case of xsl:attribute-set and xsl:key, multiple declarations) of the component.

default collation

In this specification the term default collation means the collation that is used by XPath operators such as eq and lt appearing in XPath expressions within the stylesheet.

default mode

The [xsl:]default-mode attribute defines the default mode, which is used as the default value for the mode attribute of all xsl:template and xsl:apply-templates elements within its scope.

default priority

If no priority attribute is specified on an xsl:template element, a default priority is computed, based on the syntax of the pattern supplied in the match attribute.

defining element

A string in the form of a lexical QName may occur as the value of an attribute node in a stylesheet module, or within an XPath expression contained in an attribute or text node within a stylesheet module, or as the result of evaluating an XPath expression contained in such a node. The element containing this attribute or text node is referred to as the defining element of the lexical QName.

deprecated

Some constructs defined in this specification are described as being deprecated. The use of this term implies that stylesheet authors should not use the construct, and that the construct may be removed in a later version of this specification.

dynamic error

An error that is not capable of detection until a source document is being transformed is referred to as a dynamic error.

dynamic evaluation feature

A processor that claims conformance with the dynamic evaluation featuremust evaluate the xsl:evaluate function as described in this specification.

eclipsed

An xsl:function declaration F is said to be eclipsed if the containing package includes an xsl:function declaration G such that F and G have the same name, F has lower import precedence than G, and the arity range of G includes the totality of the arity range of F.

effective value

The effective value of an attribute or text node in the stylesheet is the value after any required expansion or normalization.

effective version

The effective version of an element in a stylesheet module or package manifest is the decimal value of the [xsl:]version attribute (see 3.4 Standard Attributes) on that element or on the innermost ancestor element that has such an attribute, subject to special rules for the xsl:output and xsl:fallback elements.

embedded stylesheet module

A stylesheet module whose outermost element is the child of a non-XSLT element in a host document is referred to as an embedded stylesheet module. See 3.12 Embedded Stylesheet Modules.

enclosing mode

A mode declared by an xsl:mode declaration that has one or more contained xsl:template declarations is referred to as an enclosing mode.

EQName

An EQName is a string representing an expanded QName where the string, after removing leading and trailing whitespace, is in the form defined by the EQNameXP production in the XPath specification.

expanded QName

An expanded QName is a value in the value space of the xs:QName datatype as defined in the XDM data model (see [XDM 3.0]): that is, a triple containing namespace prefix (optional), namespace URI (optional), and local name. Two expanded QNames are equal if the namespace URIs are the same (or both absent) and the local names are the same. The prefix plays no part in the comparison, but is used only if the expanded QName needs to be converted back to a string.

explicit default

An explicit default for a parameter is indicated by the presence of either a select attribute or a non-empty sequence constructor.

explicitly mandatory

A parameter is explicitly mandatory if it is a function parameterwith no required attribute, or if the required attribute is present and has the value yes.

expression

Within this specification, the term XPath expression, or simply expression, means a string that matches the production ExprXP defined in [XPath 3.0].

extension attribute

An element from the XSLT namespace may have any attribute not from the XSLT namespace, provided that the expanded QName (see [XPath 3.0]) of the attribute has a non-null namespace URI. These attributes are referred to as extension attributes.

extension function

An extension function is a named function introduced to the static or dynamic context by mechanisms outside the scope of this specification.

extension instruction

An extension instruction is an element within a sequence constructor that is in a namespace (not the XSLT namespace) designated as an extension namespace.

extension namespace

The extension instruction mechanism allows namespaces to be designated as extension namespaces. When a namespace is designated as an extension namespace and an element with a name from that namespace occurs in a sequence constructor, then the element is treated as an instruction rather than as a literal result element.

final output state

The first of the two output states is called final output state. This state applies when instructions are writing to a final result tree.

final result tree

A final result tree is a result tree that forms part of the output of a transformation: specifically, a tree built by post-processing the items in the principal result or in a secondary result. Once created, the contents of a final result tree are not accessible within the stylesheet itself.

fixed namespace bindings

The fixed namespace bindings for a stylesheet module are established using the fixed-namespaces attribute on the xsl:stylesheet, xsl:transform, or xsl:package element enclosing the stylesheet module.

focus

When a sequence constructor is evaluated, the processor keeps track of which items are being processed by means of a set of implicit variables referred to collectively as the focus.

focus-changing construct

A focus-changing construct is a construct that has one or more operands that are evaluated with a different focus from the parent construct.

focus-setting container

The focus-setting container of a construct C is the innermost focus-changing constructF (if one exists) such that C is directly or indirectly contained in a controlled operand of F. If there is no such construct F, then the focus-setting container is the containing declaration, for example an xsl:function or xsl:template element.

forwards compatible behavior

An element is processed with forwards compatible behavior if its effective version is greater than 4.0.

free-ranging

A free-ranging construct is any construct deemed free-ranging by the rules in this section (19 Streamability).

function definition

The term function definition is defined in Section 2.2.1 Static ContextXP. It is the definition of a function that can be called statically from within an XPath expression: in the case of XSLT it typically means either a stylesheet function, or a built-in function such as those defined in [Functions and Operators 4.0]

function parameter

An xsl:param element may appear as a child of an xsl:function element, before any non-xsl:param children of that element. Such a parameter is known as a function parameter. A function parameter is a local variable with the additional property that its value can be set when the function is called, using a function call in an XPath expression.

fundamental item type

There are 28 fundamental item types: the 7 node kinds defined in [XDM 3.0] (element, attribute, etc.), the 19 primitive atomic types defined in [XML Schema Part 2], plus the types fn(*) and xs:untypedAtomic. The fundamental item types are disjoint, and every item is an instance of exactly one of them.

general streamability rules

Many constructs share the same streamability rules. These rules, referred to as the general streamability rules, are defined here.

global context item

An item that is the global context item for the transformation acts as the context item when evaluating the select expression or sequence constructor of a global variablewhose declaration is within the top-level package, as described in 5.3.3.1 Maintaining Position: the Focus. The global context item may also be available in a named template when the stylesheet is invoked as described in 2.3.4 Call-Template Invocation

global variable

A top-levelvariable-binding element declares a global variable that is visible everywhere except within any region where it is shadowed by another variable binding.

grounded

Grounded: indicates that the value returned by the construct does not contain nodes from the streamed input document

group

The xsl:for-each-group instruction allocates the items in an input sequence into groups of items (that is, it establishes a collection of sequences) based either on common values of a grouping key, or on a pattern that the initial or final item in a group must match.

grouping key

If either of the group-by or group-adjacent attributes is present, then for each item in the population a set of grouping keys is calculated, as follows: the expression contained in the group-by or group-adjacent attribute is evaluated; the result is atomized; and any xs:untypedAtomic items are cast to xs:string. If composite="yes" is specified, there is a single grouping key whose value is the resulting sequence; otherwise, there is a set of grouping keys, consisting of the distinct atomic items present in the result sequence.

guaranteed-streamable

A guaranteed-streamable construct is a construct that is declared to be streamable and that follows the particular rules for that construct to make streaming possible, as defined by the analysis in this specification.

higher-order operand

Whether or not the operand is higher-order. For this purpose an operand O of a construct C is higher-order if the semantics of C potentially require O to be evaluated more than once during a single evaluation of C.

homonymous

Two components are said to be homonymous if they have the same symbolic identifier.

identical (types)

Types S and T are considered identical for the purpose of these rules if and only if subtype(S, T) and subtype(T, S) both hold, where the subtype relation is defined in Section 3.3.1 Subtypes of Sequence TypesXP.

immediate result

The result of evaluating a sequence constructor is the sequence of items formed by concatenating the results of evaluating each of the nodes in the sequence constructor, retaining order. This is referred to as the immediate result of the sequence constructor.

implementation

A specific product that performs the functions of an XSLT processor is referred to as an implementation.

implementation-defined

In this specification, the term implementation-defined refers to a feature where the implementation is allowed some flexibility, and where the choices made by the implementation must be described in documentation that accompanies any conformance claim.

implementation-dependent

The term implementation-dependent refers to a feature where the behavior may vary from one implementation to another, and where the vendor is not expected to provide a full specification of the behavior.

implicit default

If a parameter that is not explicitly mandatory has no explicit default value, then it has an implicit default value, which is the empty sequence if there is an as attribute, or a zero-length string if not.

implicitly mandatory

If a parameter has an implicit default value which cannot be converted to the required type (that is, if it has an as attribute which does not permit the empty sequence), then the parameter is implicitly mandatory.

import precedence

A declarationD in the stylesheet is defined to have lower import precedence than another declaration E if the stylesheet level containing D would be visited before the stylesheet level containing E in a post-order traversal of the import tree (that is, a traversal of the import tree in which a stylesheet level is visited after its children). Two declarations within the same stylesheet level have the same import precedence.

import tree

The stylesheet levels making up a stylesheet are treated as forming an import tree. In the import tree, each stylesheet level has one child for each xsl:import declaration that it contains.

initial function

A stylesheet may be evaluated by calling a named stylesheet function, referred to as the initial function.

initial item

For each group, the item within the group that is first in population order is known as the initial item of the group.

initial match selection

A stylesheet may be evaluated by supplying a value to be processed, together with an initial mode. The value (which can be any sequence of items) is referred to as the initial match selection. The processing then corresponds to the effect of the xsl:apply-templates instruction.

initial mode

The initial mode is the mode used to select template rules for processing items in the initial match selection when apply-templates invocation is used to initiate a transformation.

initial named template

A stylesheet may be evaluated by selecting a named template to be evaluated; this is referred to as the initial named template.

initial sequence

The sequence to be sorted is referred to as the initial sequence.

initial setting

The initial setting of a component of the dynamic context is used when evaluating global variables and stylesheet parameters, when evaluating the use and match attributes of xsl:key, and when evaluating the initial-value of xsl:accumulator and the select expressions or contained sequence constructors of xsl:accumulator-rule

in-scope schema component

The schema components that may be referenced by name in a package are referred to as the in-scope schema components.

inspection

An operand usage of inspection indicates that the construct accesses properties of a supplied node that are available without reading its subtree.

instruction

An instruction is either an XSLT instruction or an extension instruction.

invocation construct

The following constructs are classified as invocation constructs: the instructions xsl:call-template, xsl:apply-templates, xsl:apply-imports, and xsl:next-match; XPath function calls that bind to stylesheet functions; XPath dynamic function calls; the functions accumulator-before and accumulator-after; the [xsl:]use-attribute-sets attribute. These all have the characteristic that they can cause evaluation of constructs that are not lexically contained within the calling construct.

key

A key is defined as a set of xsl:key declarations in the same package that share the same name.

key specifier

The expression in the use attribute and the sequence constructor within an xsl:key declaration are referred to collectively as the key specifier. The key specifier determines the values that may be used to find a node using this key.

lexical QName

A lexical QName is a string representing an expanded QName where the string, after removing leading and trailing whitespace, is within the lexical space of the xs:QName datatype as defined in XML Schema (see [XML Schema Part 2]): that is, a local name optionally preceded by a namespace prefix and a colon.

library package

Every package within a stylesheet, other than the top-level package, is referred to as a library package.

literal namespace URI

A namespace URI in the stylesheet tree that is being used to specify a namespace URI in the result tree is called a literal namespace URI.

literal result element

In a sequence constructor, an element in the stylesheet that does not belong to the XSLT namespace and that is not an extension instruction (see 24.2 Extension Instructions) is classified as a literal result element.

local variable

As well as being allowed as a declaration, the xsl:variable element is also allowed in sequence constructors. Such a variable is known as a local variable.

match type

The match type of a pattern is the most specific U-type that is known to match all items that the pattern can match.

merge activation

A merge activation is a single evaluation of the sequence constructor contained within the xsl:merge-action element, which occurs once for each distinct combined merge key value.

merge input sequence

A merge input sequence is an arbitrary sequenceDM30 of items which is already sorted according to the merge key specification for the corresponding merge source definition.

merge key component

A merge key component specifies one component of a merge key specification; it corresponds to a single xsl:merge-key element in the stylesheet.

merge key specification

A merge key specification consists of one or more adjacent xsl:merge-key elements which together define how the merge input sequences selected by a merge source definition are sorted. Each xsl:merge-key element defines one merge key component.

merge key value

For each item in a merge input sequence, a value is computed for each merge key component within the merge key specification. The value computed for an item by using the Nth merge key component is referred to as the Nth merge key value of that item.

merge source definition

A merge source definition is the definition of one kind of input to the merge operation. It selects zero or more merge input sequences, and it includes a merge key specification to define how the merge key values are computed for each such merge input sequence.

mode

A mode is a set of template rules; when the xsl:apply-templates instruction selects a set of items for processing, it identifies the rules to be used for processing those items by nominating a mode, explicitly or implicitly.

mode definition

All the xsl:mode declarations in a package that share the same name are grouped into a named mode definition; those that have no name are grouped into a single unnamed mode definition.

motionless

A motionless construct is any construct deemed motionless by the rules in this section (19 Streamability).

named template

Templates can be invoked by name. An xsl:template element with a name attribute defines a named template.

namespace fixup

The rules for the individual XSLT instructions that construct a result tree (see 11 Creating Nodes and Sequences) prescribe some of the situations in which namespace nodes are written to the tree. These rules, however, are not sufficient to ensure that the prescribed constraints are always satisfied. The XSLT processor must therefore add additional namespace nodes to satisfy these constraints. This process is referred to as namespace fixup.

native namespace bindings

The native namespace bindings for any element in an XSLT stylesheet module are the prefix-uri mappings defined by the namespace nodes of that element, according to the rules in [XDM 3.0].

navigation

An operand usage of navigation indicates that the construct may navigate freely from the supplied node to other nodes in the same tree, in a way that is not constrained by the streamability rules.

node pattern

A node pattern uses a subset of the syntax for path expressions, and is defined to match a node if the corresponding path expression would select the node. Node patterns may also be formed by combining other patterns using union, intersection, and difference operators.

non-contextual function call

The term non-contextual function call is used to refer to function calls that do not pass the dynamic context to the called function. This includes all calls on stylesheet functions and all dynamic function invocationsXP, (that is calls to function items as permitted by XPath 3.0). It excludes calls to some functions in the namespace http://www.w3.org/2005/xpath-functions, in particular those that explicitly depend on the context, such as the current-group and regex-group functions. It is implementation-defined whether, and under what circumstances, calls to extension functions are non-contextual.

non-positional predicate

A predicate is a non-positional predicate if it satisfies both of the following conditions:

  1. The predicate does not contain a function call or named function reference to any of the following functions, unless that call or reference occurs within a nested predicate:

    1. position

    2. last

    3. function-lookup.

    Note:

    The exception for nested predicates is there to ensure that patterns such as match="p[@code = $status[last()]] are not disqualified.

  2. The expression immediately contained in the predicate is a non-numeric expression. An expression is non-numeric if the intersection of its static type (see 19.1 Determining the Static Type of a Construct) with U{xs:decimal, xs:double, xs:float} is U{}.

non-schema-aware processor

A non-schema-aware processor is a processor that does not claim conformance with the schema-aware conformance feature. Such a processor must handle constructs associated with schema-aware processing as described in this section.

operand

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.

operand role

For every construct kind, there is a set of zero or more operand roles.

operand usage

The operand usage. This gives information, in the case where the operand value contains nodes, about how those nodes are used. The operand usage takes one of the values absorption, inspection, transmission, or navigation.

order of first appearance

There is a total ordering among groups referred to as the order of first appearance. A group G is defined to precede a group H in order of first appearance if the initial item of G precedes the initial item of H in population order. If two groups G and H have the same initial item (because the item is in both groups) then G precedes H if the grouping key of G precedes the grouping key of H in the sequence that results from evaluating the group-by expression of this initial item.

output definition

All the xsl:output declarations within a package that share the same name are grouped into a named output definition; those that have no name are grouped into a single unnamed output definition.

output state

Each instruction in the stylesheet is evaluated in one of two possible output states: final output state or temporary output state.

override

A component in a using package may override a component in a used package, provided that the visibility of the component in the used package is either abstract or public. The overriding declaration is written as a child of the xsl:override element, which in turn appears as a child of xsl:use-package.

package

An explicit package is represented by an xsl:package element, which will generally be the outermost element of an XML document. When the xsl:package element is not used explicitly, the entire stylesheet comprises a single implicit package.

package manifest

The content of the xsl:package element is referred to as the package manifest

parameter

The xsl:param element declares a parameter, which may be a stylesheet parameter, a template parameter, a function parameter, or an xsl:iterate parameter. A parameter is a variable with the additional property that its value can be set by the caller.

pattern

A pattern specifies a set of conditions on an item. An item that satisfies the conditions matches the pattern; an item that does not satisfy the conditions does not match the pattern.

picture string

The picture string is the string supplied as the second argument of the format-number function.

place marker

The xsl:number instruction performs two tasks: firstly, determining a place marker (this is a sequence of integers, to allow for hierarchic numbering schemes such as 1.12.2 or 3(c)ii), and secondly, formatting the place marker for output as a text node in the result sequence.

population

The sequence of items to be grouped, which is referred to as the population, is determined by evaluating the XPath expression contained in the select attribute.

population order

The population is treated as a sequence; the order of items in this sequence is referred to as population order.

portion

The integer literals and the optional NamePart within the version number are referred to as the portions of the version number.

posture

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.

potentially consuming

An operand is potentially consuming if at least one of the following conditions applies:

  1. The operand’s adjusted sweepS′ is consuming.

  2. The operand usage is transmission and the operand is not grounded.

predicate pattern

A predicate pattern is written as . (dot) followed by zero or more predicates in square brackets, and it matches any item for which each of the predicates evaluates to true.

principal result

A principal result: this can be any sequence of items (as defined in [XDM 3.0]).

principal stylesheet module

Within a package, one stylesheet module functions as the principal stylesheet module. The complete package is assembled by finding the stylesheet modules referenced directly or indirectly from the principal stylesheet module using xsl:include and xsl:import elements: see 3.11.2 Stylesheet Inclusion and 3.11.3 Stylesheet Import.

priority

The priority of a template rule is specified by the priority attribute on the xsl:template declaration. If no priority is specified explicitly for a template rule, its default priority is used, as defined in 6.66.5 Default Priority for Template Rules.

processing order

There is another total ordering among groups referred to as processing order. If group R precedes group S in processing order, then in the result sequence returned by the xsl:for-each-group instruction the items generated by processing group R will precede the items generated by processing group S.

processor

The software responsible for transforming source trees into result trees using an XSLT stylesheet is referred to as the processor. This is sometimes expanded to XSLT processor to avoid any confusion with other processors, for example an XML processor.

raw result

The result of invoking the selected component, after any required conversion to the declared result type of the component, is referred to as the raw result.

reference binding

The process of identifying the component to which a symbolic reference applies (possibly chosen from several homonymous alternatives) is called reference binding.

required type

The context within a stylesheet where an XPath expression appears may specify the required type of the expression. The required type indicates the type of the value that the expression is expected to return.

reserved namespace

The XSLT namespace, together with certain other namespaces recognized by an XSLT processor, are classified as reserved namespaces and must be used only as specified in this and related specifications.

result tree

The term result tree is used to refer to any tree constructed by instructions in the stylesheet. A result tree is either a final result tree or a temporary tree.

roaming

Roaming: indicates that the nodes returned by an expression could be anywhere in the tree, which inevitably means that the construct cannot be evaluated using streaming.

scanning expression

A RelativePathExpr is a scanning expression if and only if it is syntactically equivalent to some motionlesspattern.

schema-aware XSLT processor

A schema-aware XSLT processor is an XSLT processor that implements the mandatory requirements of this specification connected with the xsl:import-schema declaration, the [xsl:]validation and [xsl:]type attributes, and the ability to handle input documents whose nodes have type annotations other than xs:untyped and xs:untypedAtomic. The mandatory requirements of this specification are taken to include the mandatory requirements of XPath 3.0, as described in [XPath 3.0]. A requirement is mandatory unless the specification includes wording (such as the use of the words should or may) that clearly indicates that it is optional.

schema component

Type definitions and element and attribute declarations are referred to collectively as schema components.

schema instance namespace

The schema instance namespacehttp://www.w3.org/2001/XMLSchema-instance, with conventional prefix xsi, is used as defined in [XML Schema Part 1]

schema namespace

The schema namespacehttp://www.w3.org/2001/XMLSchema, with conventional prefix xs, is used as defined in [XML Schema Part 1]

secondary result

Zero or more secondary results: each secondary result can be any sequence of items (as defined in [XDM 3.0]).

sequence constructor

A sequence constructor is a sequence of zero or more sibling nodes in the stylesheet that can be evaluated to return a sequence of nodes, atomic items, and function items. The way that the resulting sequence is used depends on the containing instruction.

SequenceType

A SequenceType constrains the type and number of items in a sequence. The term is used both to denote the concept, and to refer to the syntactic form in which sequence types are expressed in the XPath grammar: specifically SequenceTypeXP in [XPath 3.0].

serialization

A frequent requirement is to output a final result tree as an XML document (or in other formats such as HTML). This process is referred to as serialization.

serialization error

If a transformation has successfully produced a principal result or secondary result, it is still possible that errors may occur in serializing that result . For example, it may be impossible to serialize the result using the encoding selected by the user. Such an error is referred to as a serialization error.

serialization feature

A processor that claims conformance with the serialization featuremust support the conversion of a final result tree to a sequence of octets following the rules defined in 26 Serialization.

shadows

Within a region of the stylesheet where a binding B1 is visible, B1 shadows another binding B2 having the same name as B1 if B1 occurs at a point where B2 is visible.

simplified stylesheet

A simplified stylesheet, which is a subtree rooted at a literal result element, as described in 3.8 Simplified Stylesheet Modules. This is first converted to a standard stylesheet module by wrapping it in an xsl:stylesheet element using the transformation described in 3.8 Simplified Stylesheet Modules.

singleton focus

A singleton focus based on an item J has the context item (and therefore the context node, if J is a node) set to J, and the context position and context size both set to 1 (one).

snapshot

A snapshot of a node N is a deep copy of N, as produced by the xsl:copy-of instruction with copy-namespaces set to yes, copy-accumulators set to yes, and validation set to preserve, with the additional property that for every ancestor of N, the copy also has a corresponding ancestor whose name, node-kind, and base URI are the same as the corresponding ancestor of N, and that has copies of the attributes, namespaces and accumulator values of the corresponding ancestor of N. But the ancestor has a type annotation of xs:anyType, has the properties nilled, is-id, and is-idref set to false, and has no children other than the child that is a copy of N or one of its ancestors.

sorted sequence

The sequence after sorting as defined by the xsl:sort elements is referred to as the sorted sequence.

sort key component

Within a sort key specification, each xsl:sort element defines one sort key component.

sort key specification

A sort key specification is a sequence of one or more adjacent xsl:sort elements which together define rules for sorting the items in an input sequence to form a sorted sequence.

sort key value

For each item in the initial sequence, a value is computed for each sort key component within the sort key specification. The value computed for an item by using the Nth sort key component is referred to as the Nth sort key value of that item.

source tree

The term source tree means any tree provided as input to the transformation. This includes the document containing the global context item if any, documents containing nodes present in the initial match selection, documents containing nodes supplied as the values of stylesheet parameters, documents obtained from the results of functions such as document, doc, and collection, documents read using the xsl:source-document instruction, and documents returned by extension functions or extension instructions. In the context of a particular XSLT instruction, the term source tree means any tree provided as input to that instruction; this may be a source tree of the transformation as a whole, or it may be a temporary tree produced during the course of the transformation.

stable

A sort key specification is said to be stable if its first xsl:sort element has no stable attribute, or has a stable attribute whose effective value is yes.

standard attributes

There are a number of standard attributes that may appear on any XSLT element: specifically default-collation, default-mode, default-validation, exclude-result-prefixes, expand-text, extension-element-prefixes, schema-role, use-when, version, and xpath-default-namespace.

standard error namespace

The standard error namespacehttp://www.w3.org/2005/xqt-errors, with conventional prefix err, is used for error codes defined in this specification and related specifications. It is also used for the names of certain predefined variables accessible within the scope of an xsl:catch element.

standard function namespace

The standard function namespacehttp://www.w3.org/2005/xpath-functions, with conventional prefix fn, is used for functions in the function library defined in [Functions and Operators 4.0] and for standard functions defined in this specification.

standard stylesheet module

A standard stylesheet module, which is a subtree rooted at an xsl:stylesheet or xsl:transform element.

static error

An error that can be detected by examining a stylesheet before execution starts (that is, before the source document and values of stylesheet parameters are available) is referred to as a static error.

static expression

A static expression is an XPath expression whose value must be computed during static analysis of the stylesheet.

static parameter

A static variable declared using an xsl:param element is referred to as a static parameter.

static type

The static type of a construct is such that all values produced by evaluating the construct will conform to that type. The static type of a construct is a U-type.

static variable

A top-levelvariable-binding element having the attribute static="yes" declares a static variable: that is, a global variable whose value is known during static analysis of the stylesheet.

streamability category

Stylesheet functions belong to one of a number of streamability categories: the choice of category characterizes the way in which the function handles streamed input.

streamable mode

A streamable mode is a mode that is declared in an xsl:mode declaration with the attribute streamable="yes".

streamed document

A streamed document is a source tree that is processed using streaming, that is, without constructing a complete tree of nodes in memory.

streamed node

A streamed node is a node in a streamed document.

streaming

The term streaming refers to a manner of processing in which XML documents (such as source and result documents) are not represented by a complete tree of nodes occupying memory proportional to document size, but instead are processed “on the fly” as a sequence of events, similar in concept to the stream of events notified by an XML parser to represent markup in lexical XML.

streaming feature

A processor that claims conformance with the streaming featuremust use streamed processing in cases where (a) streaming is requested (for example by using the attribute streamable="yes" on xsl:mode, or on the xsl:source-document instruction) and (b) the constructs in question are guaranteed-streamable according to this specification.

streaming parameter

The first parameter of a declared-streamablestylesheet function is referred to as a streaming parameter.

striding

Striding: indicates that the result of a construct contains a sequence of streamed nodes, in document order, that are peers in the sense that none of them is an ancestor or descendant of any other.

string value

The term string value is defined in Section 5.13 string-value Accessor DM30. Every node has a string value. For example, the string value of an element is the concatenation of the string values of all its descendant text nodes.

stylesheet

A stylesheet consists of one or more packages: specifically, one top-level package and zero or more library packages.

stylesheet function

An xsl:function declaration declares the name, parameters, and implementation of a family of stylesheet functions that can be called from any XPath expression within the stylesheet (subject to visibility rules).

stylesheet level

A stylesheet level is a collection of stylesheet modules connected using xsl:include declarations: specifically, two stylesheet modules A and B are part of the same stylesheet level if one of them includes the other by means of an xsl:include declaration, or if there is a third stylesheet module C that is in the same stylesheet level as both A and B.

stylesheet module

A package consists of one or more stylesheet modules, each one forming all or part of an XML document.

stylesheet parameter

A top-levelxsl:param element declares a stylesheet parameter. A stylesheet parameter is a global variable with the additional property that its value can be supplied by the caller when a transformation is initiated.

supplied value

The value of the variable is computed using the expression given in the select attribute or the contained sequence constructor, as described in 9.3 Values of Variables and Parameters. This value is referred to as the supplied value of the variable.

sweep

Every construct has a sweep, which is a measure of the extent to which the current position in the input stream moves during the evaluation of the expression. The sweep is one of: motionless, consuming, or free-ranging .

symbolic identifier

The symbolic identifier of a component is a composite name used to identify the component uniquely within a package. The symbolic identifier comprises the kind of component (stylesheet function, named template, accumulator, attribute set, global variable, key, or mode), the expanded QName of the component (namespace URI plus local name), and in the case of stylesheet functions, the upper bound of the arity range.

symbolic reference

The declaration of a component includes constructs that can be interpreted as references to other components by means of their symbolic identifiers. These constructs are generically referred to as symbolic references. Examples of constructs that give rise to symbolic references are the name attribute of xsl:call-template; the [xsl:]use-attribute-sets attribute of xsl:copy, xsl:element, and literal result elements; the explicit or implicit mode attribute of xsl:apply-templates; XPath variable references referring to global variables; XPath static function calls (including partial function applications) referring to stylesheet functions; and named function references (example: my:f#1) referring to stylesheet functions.

tail position

An instructionJ is in a tail position within a sequence constructorSC if it satisfies one of the following conditions:

target expression

The string that results from evaluating the expression in the xpath attribute is referred to as the target expression.

target namespace URI

The namespace URI that is to be used in the result tree as a substitute for a literal namespace URI is called the target namespace URI.

template

An xsl:template declaration defines a template, which contains a sequence constructor; this sequence constructor is evaluated to determine the result of the template. A template can serve either as a template rule, invoked by matching items against a pattern, or as a named template, invoked explicitly by name. It is also possible for the same template to serve in both capacities.

template parameter

An xsl:param element may appear as a child of an xsl:template element, before any non-xsl:param children of that element. Such a parameter is known as a template parameter. A template parameter is a local variable with the additional property that its value can be set when the template is called, using any of the instructions xsl:call-template, xsl:apply-templates, xsl:apply-imports, or xsl:next-match.

template rule

A stylesheet contains a set of template rules (see 6 Template Rules). A template rule has three parts: a pattern that is matched against selected items (often but not necessarily nodes), a (possibly empty) set of template parameters, and a sequence constructor that is evaluated to produce a sequence of items.

temporary output state

The second of the two output states is called temporary output state. This state applies when instructions are writing to a temporary tree or any other non-final destination.

temporary tree

The term temporary tree means any tree that is neither a source tree nor a final result tree.

text value template

In a text node that is designated as a text value template, expressions can be used by surrounding each expression with curly brackets ({}).

top-level

An element occurring as a child of an xsl:package, xsl:stylesheet, xsl:transform, or xsl:override element is called a top-level element.

top-level package

For a given transformation, one package functions as the top-level package. The complete stylesheet is assembled by finding the packages referenced directly or indirectly from the top-level package using xsl:use-package declarations: see 3.5.2 Dependencies between Packages.

transmission

An operand usage of transmission indicates that the construct will (potentially) return a supplied node as part of its result to the calling construct (that is, to its parent in the construct tree).

traversal

A traversal of a tree is a sequence of traversal events.

traversal-event

a traversal event (shortened to event in this section) is a pair comprising a phase (start or end) and a node.

tree

The term tree is used (as in [XDM 3.0]) to refer to the aggregate consisting of a parentless node together with all its descendant nodes, plus all their attributes and namespaces.

tunnel parameter

A parameter passed to a template may be defined as a tunnel parameter. Tunnel parameters have the property that they are automatically passed on by the called template to any further templates that it calls, and so on recursively.

type-adjusted posture and sweep

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.

type annotation

The term type annotation is used in this specification to refer to the value returned by the dm:type-name accessor of a node: see Section 5.14 type-name Accessor DM30.

type-determined usage

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.

typed value

The term typed value is defined in Section 5.15 typed-value Accessor DM30. Every node, other than an element whose type annotation identifies it as having element-only content, has a typed value. For example, the typed value of an attribute of type xs:IDREFS is a sequence of zero or more xs:IDREF values.

type error

Certain errors are classified as type errors. A type error occurs when the value supplied as input to an operation is of the wrong type for that operation, for example when an integer is supplied to an operation that expects a node.

type pattern

A type pattern can be written as type(T) (where T is an ItemTypeXP followed by zero or more predicates in square brackets, and it matches any item of type T which each of the predicates evaluates to true.

unnamed mode

The unnamed mode is the default mode used when no mode attribute is specified on an xsl:apply-templates instruction or xsl:template declaration, unless a different default mode has been specified using the [xsl:]default-mode attribute of a containing element.

URI Reference

Within this specification, the term URI Reference, unless otherwise stated, refers to a string in the lexical space of the xs:anyURI datatype as defined in [XML Schema Part 2].

use

If a package Q contains an xsl:use-package element that references package P, then package Q is said to use package P. In this relationship package Q is referred to as the using package, package P as the used package.

user-defined data element

In addition to declarations, the xsl:stylesheet element may contain among its children any element not from the XSLT namespace, provided that the expanded QName of the element has a non-null namespace URI. Such elements are referred to as user-defined data elements.

U-type

A U-type is a set of fundamental item types.

vacuous

An item is vacuous if it is one of the following: a zero-length text node; a document node with no children; an atomic item which, on casting to xs:string, produces a zero-length string; or an array which on flattening using the array:flatten function produces either an empty sequence or a sequence consisting entirely of vacuous items.

value

A variable is a binding between a name and a value. The value of a variable is any sequence (of nodes, atomic items, and/or function items), as defined in [XDM 3.0].

value template

Collectively, attribute value templates and text value templates are referred to as value templates.

variable

The xsl:variable element declares a variable, which may be a global variable or a local variable.

variable-binding element

The two elements xsl:variable and xsl:param are referred to as variable-binding elements.

visibility

The visibility of a component is one of: private, public, abstract, final, or hidden.

whitespace text node

A whitespace text node is a text node whose content consists entirely of whitespace characters (that is, U+0009 (TAB) , U+000A (NEWLINE) , U+000D (CARRIAGE RETURN) , or U+0020 (SPACE) ).

XML namespace

The XML namespace, defined in [Namespaces in XML] as http://www.w3.org/XML/1998/namespace, is used for attributes such as xml:lang, xml:space, and xml:id.

XPath 1.0 compatibility mode

The term XPath 1.0 compatibility mode is defined in Section 2.2.1 Static ContextXP. This is a setting in the static context of an XPath expression; it has two values, true and false. When the value is set to true, the semantics of function calls and certain other operations are adjusted to give a greater degree of backwards compatibility between XPath 4.0 and XPath 1.0.

XSLT 1.0 behavior

An element in the stylesheet is processed with XSLT 1.0 behavior if its effective version is equal to 1.0.

XSLT 1.0 compatibility feature

A processor that claims conformance with the XSLT 1.0 compatibility featuremust support the processing of stylesheet instructions and XPath expressions with XSLT 1.0 behavior, as defined in 3.9 Backwards Compatible Processing.

XSLT 2.0 behavior

An element is processed with XSLT 2.0 behavior if its effective version is equal to 2.0.

XSLT 3.0 behavior

An element is processed with XSLT 3.0 behavior if its effective version is equal to 3.0.

XSLT element

An XSLT element is an element in the XSLT namespace whose syntax and semantics are defined in this specification.

XSLT instruction

An XSLT instruction is an XSLT element whose syntax summary in this specification contains the annotation <!-- category: instruction -->.

XSLT namespace

The XSLT namespace has the URI http://www.w3.org/1999/XSL/Transform. It is used to identify elements, attributes, and other names that have a special meaning defined in this specification.

E Pattern Syntax Summary (Non-Normative)

This appendix gives the grammar for XSLT patterns. The top-level rule for patterns is Pattern40.

This is an extension of the grammar for XPath expressions. The extended BNF notation is explained at Section A.1.1 NotationXP.

Productions that are identical to their counterparts in XPath 4.0 are suffixed XP and link to the corresponding production in the XPath 4.0 specification. Productions whose names end with P are restrictions of the corresponding XPath production: for example, ArgumentListP is a restricted form of the XPath production ArgumentList.

AbbrevForwardStep::=("@" NodeTestXP) | SimpleNodeTestXP
AbbrevReverseStep::=".."
AdditiveExpr::=MultiplicativeExprXP (("+" | "-") MultiplicativeExprXP)*
AndExpr::=ComparisonExprXP ("and" ComparisonExprXP)*
AnyArrayType::="array" "(" "*" ")"
AnyFunctionType::=("function" | "fn") "(" "*" ")"
AnyItemTest::="item" "(" ")"
AnyKindTest::="node" "(" ")"
AnyMapType::="map" "(" "*" ")"
AnyRecordType::="record" "(" "*" ")"
Argument::=ExprSingleXP | ArgumentPlaceholderXP
ArgumentList::="(" ((PositionalArgumentsXP ("," KeywordArgumentsXP)?) | KeywordArgumentsXP)? ")"
ArgumentListP::="(" (ArgumentP ** ",") ")"
ArgumentP::=VarRefXP | LiteralXP
ArgumentPlaceholder::="?"
ArrayConstructor::=SquareArrayConstructorXP | CurlyArrayConstructorXP
ArrayType::=AnyArrayTypeXP | TypedArrayTypeXP
ArrowExpr::=UnaryExprXP (SequenceArrowTargetXP | MappingArrowTargetXP)*
ArrowTarget::=FunctionCallXP | RestrictedDynamicCallXP
AttributeName::=EQNameXP
AttributeTest::="attribute" "(" (NameTestUnionXP ("," TypeNameXP)?)? ")"
AxisStep::=(ReverseStepXP | ForwardStepXP) PredicateXP*
AxisStepP::=ForwardStepPPredicateXP*
BracedAction::=EnclosedExprXP
CastableExpr::=CastExprXP ("castable" "as" CastTargetXP "?"?)?
CastExpr::=PipelineExprXP ("cast" "as" CastTargetXP "?"?)?
CastTarget::=TypeNameXP
ChoiceItemType::="(" (ItemTypeXP ++ "|") ")"
CommentTest::="comment" "(" ")"
ComparisonExpr::=OtherwiseExprXP ((ValueCompXP | GeneralCompXP | NodeCompXP) OtherwiseExprXP)?
ContextValueRef::="."
CurlyArrayConstructor::="array" EnclosedExprXP
DocumentTest::="document-node" "(" (ElementTestXP | SchemaElementTestXP | NameTestUnionXP)? ")"
DynamicFunctionCall::=PostfixExprXPPositionalArgumentListXP
ElementName::=EQNameXP
ElementTest::="element" "(" (NameTestUnionXP ("," TypeNameXP "?"?)?)? ")"
EnclosedExpr::="{" ExprXP? "}"
EnumerationType::="enum" "(" (StringLiteralXP ++ ",") ")"
EQName::=QName | URIQualifiedNameXP
Expr::=(ExprSingleXP ++ ",")
ExprSingle::=ForExprXP
| LetExprXP
| QuantifiedExprXP
| IfExprXP
ExtensibleFlag::="," "*"
FieldDeclaration::=FieldNameXP "?"? ("as" SequenceTypeXP)?
FieldName::=NCNameXP | StringLiteralXP
FilterExpr::=PostfixExprXPPredicateXP
FilterExprAM::=PostfixExprXP "?[" ExprXP "]"
ForBinding::=ForItemBindingXP | ForMemberBindingXP | ForEntryBindingXP
ForClause::="for" (ForBindingXP ++ ",")
ForEntryBinding::=((ForEntryKeyBindingXPForEntryValueBindingXP?) | ForEntryValueBindingXP) PositionalVarXP? "in" ExprSingleXP
ForEntryKeyBinding::="key" VarNameAndTypeXP
ForEntryValueBinding::="value" VarNameAndTypeXP
ForExpr::=ForClauseXPForLetReturnXP
ForItemBinding::=VarNameAndTypeXPPositionalVarXP? "in" ExprSingleXP
ForLetReturn::=ForExprXP | LetExprXP | ("return" ExprSingleXP)
ForMemberBinding::="member" VarNameAndTypeXPPositionalVarXP? "in" ExprSingleXP
ForwardAxis::=("attribute"
| "child"
| "descendant"
| "descendant-or-self"
| "following"
| "following-or-self"
| "following-sibling"
| "following-sibling-or-self"
| "namespace"
| "self") "::"
ForwardAxisP::=("child" "::")
| ("descendant" "::")
| ("attribute" "::")
| ("self" "::")
| ("descendant-or-self" "::")
| ("namespace" "::")
ForwardStep::=(ForwardAxisXPNodeTestXP) | AbbrevForwardStepXP
ForwardStepP::=(ForwardAxisPNodeTestXP) | AbbrevForwardStepXP
FunctionBody::=EnclosedExprXP
FunctionCall::=EQNameXPArgumentListXP
/* xgs: reserved-function-names */
/* gn: parens */
FunctionCallP::=OuterFunctionNameArgumentListP
FunctionItemExpr::=NamedFunctionRefXP | InlineFunctionExprXP
FunctionSignature::="(" ParamListXP ")" TypeDeclarationXP?
FunctionType::=AnyFunctionTypeXP
| TypedFunctionTypeXP
GeneralComp::="=" | "!=" | "<" | "<=" | ">" | ">="
IfExpr::="if" "(" ExprXP ")" (UnbracedActionsXP | BracedActionXP)
InlineFunctionExpr::=MethodAnnotationXP* ("function" | "fn") FunctionSignatureXP? FunctionBodyXP
InstanceofExpr::=TreatExprXP ("instance" "of" SequenceTypeXP)?
IntersectExceptExpr::=InstanceofExprXP (("intersect" | "except") InstanceofExprXP)*
IntersectExceptExprP::=PathExprP (("intersect" | "except") PathExprP)*
ItemType::=AnyItemTestXP | TypeNameXP | KindTestXP | FunctionTypeXP | MapTypeXP | ArrayTypeXP | RecordTypeXP | EnumerationTypeXP | ChoiceItemTypeXP
KeySpecifier::=NCNameXP | IntegerLiteral | StringLiteralXP | VarRefXP | ParenthesizedExprXP | LookupWildcardXP | TypeSpecifierXP
KeySpecifierP::=NCNameXP | IntegerLiteral | StringLiteralXP | VarRefXP | LookupWildcardXP | TypeSpecifierXP
KeywordArgument::=EQNameXP ":=" ArgumentXP
KeywordArguments::=(KeywordArgumentXP ++ ",")
KindTest::=DocumentTestXP
| ElementTestXP
| AttributeTestXP
| SchemaElementTestXP
| SchemaAttributeTestXP
| PITestXP
| CommentTestXP
| TextTestXP
| NamespaceNodeTestXP
| AnyKindTestXP
LabelPattern::=(("?" | "??") KeySpecifierP)+
LetBinding::=VarNameAndTypeXP ":=" ExprSingleXP
LetClause::="let" (LetBindingXP ++ ",")
LetExpr::=LetClauseXPForLetReturnXP
Literal::=NumericLiteralXP | StringLiteralXP | QNameLiteralXP
Lookup::=("?" | "??") (ModifierXP "::")? KeySpecifierXP
LookupExpr::=PostfixExprXPLookupXP
LookupWildcard::="*"
MapConstructor::="map"? "{" (MapConstructorEntryXP ** ",") "}"
MapConstructorEntry::=MapKeyExprXP ":" MapValueExprXP
MapKeyExpr::=ExprSingleXP
MappingArrowTarget::="=!>" ArrowTargetXP
MapType::=AnyMapTypeXP | TypedMapTypeXP
MapValueExpr::=ExprSingleXP
MethodAnnotation::="%method"
Modifier::="pairs" | "keys" | "values" | "items"
MultiplicativeExpr::=UnionExprXP (("*" | "×" | "div" | "÷" | "idiv" | "mod") UnionExprXP)*
NamedFunctionRef::=EQNameXP "#" IntegerLiteral
/* xgs: reserved-function-names */
NamespaceNodeTest::="namespace-node" "(" ")"
NameTest::=EQNameXP | WildcardXP
NameTestUnion::=(NameTestXP ++ "|")
NodeComp::="is" | "<<" | ">>"
NodePattern::=UnionExprP
NodeTest::=UnionNodeTestXP | SimpleNodeTestXP
NumericLiteral::=IntegerLiteral | HexIntegerLiteral | BinaryIntegerLiteral | DecimalLiteral | DoubleLiteral
OccurrenceIndicator::="?" | "*" | "+"
/* xgs: occurrence-indicators */
OrExpr::=AndExprXP ("or" AndExprXP)*
OtherwiseExpr::=StringConcatExprXP ("otherwise" StringConcatExprXP)*
OuterFunctionName::=EQNameXP
ParamList::=(VarNameAndTypeXP ** ",")
ParenthesizedExpr::="(" ExprXP? ")"
ParenthesizedExprP::="(" UnionExprP ")"
PathExpr::=("/" RelativePathExprXP?)
| ("//" RelativePathExprXP)
| RelativePathExprXP
/* xgs: leading-lone-slash */
PathExprP::=RootedPath
| ("/" RelativePathExprP?)
| ("//" RelativePathExprP)
| RelativePathExprP
/* xgs: leading-lone-slash */
Pattern40::=PredicatePattern | TypePattern | NodePattern | LabelPattern
PipelineExpr::=ArrowExprXP ("->" ArrowExprXP)*
PITest::="processing-instruction" "(" (NCNameXP | StringLiteralXP)? ")"
PositionalArgumentList::="(" PositionalArgumentsXP? ")"
PositionalArguments::=(ArgumentXP ++ ",")
PositionalVar::="at" VarNameXP
PostfixExpr::=PrimaryExprXP | FilterExprXP | DynamicFunctionCallXP | LookupExprXP | FilterExprAMXP
PostfixExprP::=(FunctionCallP | ParenthesizedExprP) PredicateXP*
Predicate::="[" ExprXP "]"
PredicatePattern::="." PredicateXP*
PrimaryExpr::=LiteralXP
| VarRefXP
| ParenthesizedExprXP
| ContextValueRefXP
| FunctionCallXP
| FunctionItemExprXP
| MapConstructorXP
| ArrayConstructorXP
| StringTemplateXP
| UnaryLookupXP
QNameLiteral::="#" EQNameXP
/* ws: explicit */
QuantifiedExpr::=("some" | "every") (QuantifierBindingXP ++ ",") "satisfies" ExprSingleXP
QuantifierBinding::=VarNameAndTypeXP "in" ExprSingleXP
RangeExpr::=AdditiveExprXP ("to" AdditiveExprXP)?
RecordType::=AnyRecordTypeXP | TypedRecordTypeXP
RelativePathExpr::=StepExprXP (("/" | "//") StepExprXP)*
RelativePathExprP::=StepExprP (("/" | "//") StepExprP)*
RestrictedDynamicCall::=(VarRefXP | ParenthesizedExprXP | FunctionItemExprXP | MapConstructorXP | ArrayConstructorXP) PositionalArgumentListXP
ReverseAxis::=("ancestor"
| "ancestor-or-self"
| "parent"
| "preceding"
| "preceding-or-self"
| "preceding-sibling"
| "preceding-sibling-or-self") "::"
ReverseStep::=(ReverseAxisXPNodeTestXP) | AbbrevReverseStepXP
RootedPath::=VarRefXPPredicateXP* (("/" | "//") RelativePathExprP)?
SchemaAttributeTest::="schema-attribute" "(" AttributeNameXP ")"
SchemaElementTest::="schema-element" "(" ElementNameXP ")"
SequenceArrowTarget::="=>" ArrowTargetXP
SequenceType::=("empty-sequence" "(" ")")
| (ItemTypeXPOccurrenceIndicatorXP?)
SimpleMapExpr::=PathExprXP ("!" PathExprXP)*
SimpleNodeTest::=KindTestXP | NameTestXP
SquareArrayConstructor::="[" (ExprSingleXP ** ",") "]"
StepExpr::=PostfixExprXP | AxisStepXP
StepExprP::=PostfixExprP | AxisStepP
StringConcatExpr::=RangeExprXP ("||" RangeExprXP)*
StringTemplate::="`" (StringTemplateFixedPartXP | StringTemplateVariablePartXP)* "`"
/* ws: explicit */
StringTemplateFixedPart::=((Char - ('{' | '}' | '`')) | "{{" | "}}" | "``")*
/* ws: explicit */
StringTemplateVariablePart::=EnclosedExprXP
/* ws: explicit */
TextTest::="text" "(" ")"
TreatExpr::=CastableExprXP ("treat" "as" SequenceTypeXP)?
TypedArrayType::="array" "(" SequenceTypeXP ")"
TypeDeclaration::="as" SequenceTypeXP
TypedFunctionParam::=("$" EQNameXP "as")? SequenceTypeXP
TypedFunctionType::=("function" | "fn") "(" (TypedFunctionParamXP ** ",") ")" "as" SequenceTypeXP
TypedMapType::="map" "(" ItemTypeXP "," SequenceTypeXP ")"
TypedRecordType::="record" "(" (FieldDeclarationXP ** ",") ExtensibleFlagXP? ")"
TypeName::=EQNameXP
TypePattern::=(WrappedItemTest | AnyItemTestXP | FunctionTypeXP | MapTypeXP | ArrayTypeXP | RecordTypeXP | EnumerationTypeXP) PredicateXP*
TypeSpecifier::="~[" SequenceTypeXP "]"
UnaryExpr::=("-" | "+")* ValueExprXP
UnaryLookup::=LookupXP
UnbracedActions::="then" ExprSingleXP "else" ExprSingleXP
UnionExpr::=IntersectExceptExprXP (("union" | "|") IntersectExceptExprXP)*
UnionExprP::=IntersectExceptExprP (("union" | "|") IntersectExceptExprP)*
UnionNodeTest::="(" SimpleNodeTestXP ("|" SimpleNodeTestXP)* ")"
ValueComp::="eq" | "ne" | "lt" | "le" | "gt" | "ge"
ValueExpr::=SimpleMapExprXP
VarName::="$" EQNameXP
VarNameAndType::="$" EQNameXPTypeDeclarationXP?
VarRef::="$" EQNameXP
Wildcard::="*"
| (NCName ":" "*")
| ("*" ":" NCName)
| (BracedURILiteral "*")
/* ws: explicit */
WrappedItemTest::="type" ChoiceItemTypeXP

F Checklist of Implementation-Defined Features (Non-Normative)

This appendix provides a summary of XSLT language features whose effect is explicitly implementation-defined. The conformance rules (see 27 Conformance) require vendors to provide documentation that explains how these choices have been exercised.

The implementation-defined features are grouped into categories for convenience.

F.1 Application Programming Interfaces

This category covers interfaces for initiating a transformation, setting its parameters, initializing the static and dynamic context, and collecting the results. In general terms, it is implementation defined how input is passed to the processor and how it returns its output. This includes the interpretation of URIs used to refer to stylesheet packages and modules, source documents and collections, collations, and result documents.

More specifically:

  1. If the initialization of any global variables or parameter depends on the context item, a dynamic error can occur if the context item is absent. It is implementation-defined whether this error occurs during priming of the stylesheet or subsequently when the variable is referenced; and it is implementation-defined whether the error occurs at all if the variable or parameter is never referenced. (See 2.3.2 Priming a Stylesheet)

  2. The way in which an XSLT processor is invoked, and the way in which values are supplied for the source document, starting node, stylesheet parameters, and base output URI, are implementation-defined. (See 2.3.2 Priming a Stylesheet)

  3. The way in which a base output URI is established is implementation-defined (See 2.3.6.2 Serializing the Result)

  4. It is implementation-defined how a package is located given its name and version, and which version of a package is chosen if several are available. (See 3.5.2 Dependencies between Packages)

  5. In the absence of an [xsl:]default-collation attribute, the default collation may be set by the calling application in an implementation-defined way. (See 3.7.2 The default-collation Attribute)

  6. It is implementation-defined what forms of URI reference are acceptable in the href attribute of the xsl:include and xsl:import elements, for example, the URI schemes that may be used, the forms of fragment identifier that may be used, and the media types that are supported. The way in which the URI reference is used to locate a representation of a stylesheet module, and the way in which the stylesheet module is constructed from that representation, are also implementation-defined. (See 3.11.1 Locating Stylesheet Modules)

  7. Implementations may provide user options that relax the requirement for the doc and collection functions (and therefore, by implication, the document function) to return stable results. The manner in which such user options are provided, if at all, is implementation-defined. (See 5.3.3 Initializing the Dynamic Context)

  8. Streamed processing may be initiated by invoking the transformation with an initial mode declared as streamable, while supplying the initial match selection (in an implementation-defined way) as a streamed document. (See 6.7.76.6.6 Streamable Templates)

  9. The mechanism by which the caller supplies a value for a stylesheet parameter is implementation-defined. (See 9.5 Global Variables and Parameters)

  10. The detail of any external mechanism allowing a processor to enable or disable checking of assertions is implementation-defined. (See 23.2 Assertions)

  11. The way in which the results of the transformation are delivered to an application is implementation-defined. (See 25 Transformation Results)

  12. It is implementation-defined how the URI appearing in the href attribute of xsl:result-document affects the way in which the result tree is delivered to the application. There may be restrictions on the form of this URI. (See 25.1 Creating Secondary Results)

  13. If serialization is supported, then the location to which a final result tree is serialized is implementation-defined, subject to the constraint that relative URI references used to reference one tree from another remain valid. (See 26.2 Serialization parameters)

F.7 Detection and Reporting of Errors

Some aspects of error handling are implementation-defined:

  1. It is implementation-defined whether type errors are raised statically. (See 2.14 Error Handling)

  2. If the effective version of any element in the stylesheet is not 1.0 or 2.0 but is less than 4.0, the recommended action is to raise a static error; however, processors may recognize such values and process the element in an implementation-defined way. (See 3.9 Backwards Compatible Processing)

  3. The default values for the warning-on-no-match and warning-on-multiple-match attributes of xsl:mode are implementation-defined. (See 6.7.16.6.1 Declaring Modes)

  4. The form of any warnings output when there is no matching template rule, or when there are multiple matching template rules, is implementation-defined. (See 6.7.16.6.1 Declaring Modes)

  5. The destination and formatting of messages written using the xsl:message instruction are implementation-defined. (See 23.1 Messages)

G Summary of Available Functions (Non-Normative)

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.56.6.4 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. The new value on-no-match="shallow-copy-all" is designed for processing trees of maps and arrays, such as arise from parsing JSON.

    See 6.7.4 Built-in Templates: Shallow Copy All

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

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

  16. Named record types are introduced.

    See 5.5.2 Named Record Types

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

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

    See 8.4 Try/Catch

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

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

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

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

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

    See 13.1.2 Comparing Sort Key Values

  24. 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.16.6.1 Declaring Modes

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

    See 6.66.5 Default Priority for Template Rules

  26. Label patterns are new in XSLT 4.0. They are used for matching values occurring within a tree of maps and array, such as occurs as the result of parsing JSON.

    See 5.4.2.5 Label Patterns

    When arrays and maps are processed using xsl:apply-templates, they are pinned, making additional properties (such as the key of a map entry) available within match patterns.

    See 6.3.3 Applying Templates to Maps and Arrays

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

    See 6.96.8 Overriding Template Rules

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

    See 11.11 The xsl:select Instruction

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

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

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

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

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

  34. PR 406 

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

    See 22.1 Array Construction

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

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

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

  38. 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.66.6.5 Enclosing Modes

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

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

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

  42. 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.86.7 Built-in Template Rules

  43. 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.16.6.1 Declaring Modes

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

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

  46. PR 1254 

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

    See 25.4 Validation

  47. PR 1306 

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

    See 11.10 The xsl:sequence Instruction

  48. PR 1361 

    The term atomic value has been replaced by atomic item.

    See 2.1 Terminology

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

  50. PR 1442 

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

    See 6.66.5 Default Priority for Template Rules

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

  52. PR 1689 

    Composite merge keys are now allowed.

    See 15 Merging

  53. PR 1703 

    Ordered maps are introduced.

    See 21.1 Map Instructions

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

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

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

  57. PR 2006 

    A new function fn:apply-templates is introduced.

    See 6.7.36.3.4 The apply-templates Function