View Old View New View Both View Only Previous Next

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

W3C

XSL Transformations (XSLT) Version 4.0

W3C Editor's Draft 23 February 2026

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

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


Abstract

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

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

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

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

Status of this Document

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

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

Dedication

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


11 Creating Nodes and Sequences

This section describes instructions that directly create new nodes, or sequences of nodes, atomic items, and/or function items.

11.1 Literal Result Elements

[Definition: 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.] A literal result element is evaluated to construct a new element node with the same expanded QName (that is, the same namespace URI, local name, and namespace prefix). The result of evaluating a literal result element is a node sequence containing one element, the newly constructed element node.

The content of the element is a sequence constructor (see 5.8 Sequence Constructors). The sequence obtained by evaluating this sequence constructor, after prepending any attribute nodes produced as described in 11.1.2 Attribute Nodes for Literal Result Elements and namespace nodes produced as described in 11.1.3 Namespace Nodes for Literal Result Elements, is used to construct the content of the element, following the rules in 5.8.1 Constructing Complex Content

The base URI of the new element is copied from the base URI of the literal result element in the stylesheet, unless the content of the new element includes an xml:base attribute, in which case the base URI of the new element is the value of that attribute, resolved (if it is a relative URI reference) against the base URI of the literal result element in the stylesheet. (Note, however, that this is only relevant when creating a parentless element. When the literal result element is copied to form a child of an element or document node, the base URI of the new copy is taken from that of its new parent.)

11.1.4 Namespace Aliasing

When a stylesheet is used to define a transformation whose output is itself a stylesheet module, or in certain other cases where the result document uses namespaces that it would be inconvenient to use in the stylesheet, namespace aliasing can be used to declare a mapping between a namespace URI used in the stylesheet and the corresponding namespace URI to be used in the result document.

[Definition: 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.]

[Definition: 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.]

Either of the literal namespace URI or the target namespace URI can be null: this is treated as a reference to the set of names that are in no namespace.

<!-- Category: declaration -->
<xsl:namespace-alias
  stylesheet-prefix = prefix | "#default"
  result-prefix = prefix | "#default" />

[Definition: 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.]

The effect is that when names in the namespace identified by the literal namespace URI are copied to the result tree, the namespace URI in the result tree will be the target namespace URI, instead of the literal namespace URI. This applies to:

  • the namespace URI in the expanded QName of a literal result element in the stylesheet

  • the namespace URI in the expanded QName of an attribute specified on a literal result element in the stylesheet

The effect of an xsl:namespace-alias declaration is local to the package in which it appears: that is, it only affects the result of literal result elements within the same package.

Where namespace aliasing changes the namespace URI part of the expanded QName containing the name of an element or attribute node, the namespace prefix in that expanded QName is replaced by the prefix indicated by the result-prefix attribute of the xsl:namespace-alias declaration.

The xsl:namespace-alias element declares that the namespace URI bound to the prefix specified by the stylesheet-prefix is the literal namespace URI, and the namespace URI bound to the prefix specified by the result-prefix attribute is the target namespace URI. Thus, the stylesheet-prefix attribute specifies the namespace URI that will appear in the stylesheet, and the result-prefix attribute specifies the corresponding namespace URI that will appear in the result tree.

Note:

It is the native namespace bindings that apply, not the fixed namespace bindings. More specifically: if a prefix p appears in the stylesheet-prefix or result-prefix attribute, there must be an in-scope namespace declaration of the form xmlns:p="...."; it is not sufficient to declare the namespace in the fixed-namespaces attribute of the xsl:stylesheet element.

The default namespace (as declared by xmlns) may be specified by using #default instead of a prefix. If no default namespace is in force, specifying #default denotes the null namespace URI. This allows elements that are in no namespace in the stylesheet to acquire a namespace in the result document, or vice versa. Defining an alias for the null namespace URI does not affect no-namespace attributes; these remain in no namespace. However, where result-prefix="#default" is specified and no default namespace is in force, attributes whose namespace matches the literal namespace URI are renamed to be in no namespace. [XSLT 3.0 Erratum E48, bug 30397]

If a literal namespace URI is declared to be an alias for multiple different target namespace URIs, then the declaration with the highest import precedence is used.

[ERR XTSE0810] It is a static error if within a package there is more than one such declaration with the same literal namespace URI and the same import precedence and different values for the target namespace URI, unless there is also an xsl:namespace-alias declaration with the same literal namespace URI and a higher import precedence.

No error occurs if there is more than one such xsl:namespace-alias declaration having the same literal namespace URI and the same target namespace URI, even if the result-prefix differs; in this case the result-prefix used is the one that appears last in declaration order.

[ERR XTSE0812] It is a static error if a value other than #default is specified for either the stylesheet-prefix or the result-prefix attributes of the xsl:namespace-alias element when there is no in-scope binding for that namespace prefix.

When a literal result element is processed, its namespace nodes are handled as follows:

In the event that the same URI is used as a literal namespace URI and a target namespace URI, the second of these rules takes precedence.

Note:

These rules achieve the effect that the element generated from the literal result element will have an in-scope namespace node that binds the result-prefix to the target namespace URI, provided that the namespace declaration associating this prefix with this URI is in scope for both the xsl:namespace-alias instruction and for the literal result element. Conversely, the stylesheet-prefix and the literal namespace URI will not normally appear in the result tree.

Example: Using xsl:namespace-alias to Generate a Stylesheet

When literal result elements are being used to create element, attribute, or namespace nodes that use the XSLT namespace URI, the stylesheet may use an alias.

For example, the stylesheet

<xsl:stylesheet
  version="3.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:fo="http://www.w3.org/1999/XSL/Format"
  xmlns:axsl="file://namespace.alias">

<xsl:namespace-alias stylesheet-prefix="axsl" result-prefix="xsl"/>

<xsl:template match="/">
  <axsl:stylesheet version="3.0">
    <xsl:apply-templates/>
  </axsl:stylesheet>
</xsl:template>

<xsl:template match="elements">
  <axsl:template match="/">
     <axsl:comment select="system-property('xsl:version')"/>
     <axsl:apply-templatesxsl:apply-templates/>
  </axsl:template>
</xsl:template>

<xsl:template match="block">
  <axsl:template match="{.}">
     <fo:block><axsl:apply-templates/></fo:block>
  </axsl:template>
</xsl:template>

</xsl:stylesheet>

will generate an XSLT stylesheet from a document of the form:

<elements>
<block>p</block>
<block>h1</block>
<block>h2</block>
<block>h3</block>
<block>h4</block>
</elements>

The output of the transformation will be a stylesheet such as the following. Whitespace has been added for clarity. Note that an implementation may output different namespace prefixes from those appearing in this example; however, the rules guarantee that there will be a namespace node that binds the prefix xsl to the URI http://www.w3.org/1999/XSL/Transform, which makes it safe to use the QName xsl:version in the content of the generated stylesheet.

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

<xsl:template match="/">
  <xsl:comment select="system-property('xsl:version')"/>
  <xsl:apply-templates/>
</xsl:template>
  
<xsl:template match="p">
  <fo:block><xsl:apply-templates/></fo:block>
</xsl:template>

<xsl:template match="h1">
  <fo:block><xsl:apply-templates/></fo:block>
</xsl:template>

<xsl:template match="h2">
  <fo:block><xsl:apply-templates/></fo:block>
</xsl:template>

<xsl:template match="h3">
  <fo:block><xsl:apply-templates/></fo:block>
</xsl:template>

<xsl:template match="h4">
  <fo:block><xsl:apply-templates/></fo:block>
</xsl:template>

</xsl:stylesheet>

Note:

It may be necessary also to use aliases for namespaces other than the XSLT namespace URI. For example, it can be useful to define an alias for the namespace http://www.w3.org/2001/XMLSchema-instance, so that the stylesheet can use the attributes xsi:type, xsi:nil, and xsi:schemaLocation on a literal result element, without running the risk that a schema processor will interpret these as applying to the stylesheet itself. Equally, literal result elements belonging to a namespace dealing with digital signatures might cause XSLT stylesheets to be mishandled by general-purpose security software; using an alias for the namespace would avoid the possibility of such mishandling.

Example: Aliasing the XML Namespace

It is possible to define an alias for the XML namespace.

<xsl:stylesheet xmlns:axml="http://www.example.com/alias-xml"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                version="3.0">

<xsl:namespace-alias stylesheet-prefix="axml" result-prefix="xml"/>

<xsl:template match="/">
  <name axml:space="preserve">
    <first>James</first>
    <xsl:text> </xsl:text>
    <last>Clark</last>
  </name>
</xsl:template>

</xsl:stylesheet>

produces the output:

<name xml:space="preserve"><first>James</first> <last>Clark</last></name>

This allows an xml:space attribute to be generated in the output without affecting the way the stylesheet is parsed. The same technique can be used for other attributes such as xml:lang, xml:base, and xml:id.

Note:

Namespace aliasing is only necessary when literal result elements are used. The problem of reserved namespaces does not arise when using xsl:element and xsl:attribute to construct the result tree. Therefore, as an alternative to using xsl:namespace-alias, it is always possible to achieve the desired effect by replacing literal result elements with xsl:element and xsl:attribute instructions.