11 Creating Nodes and Sequences

This section describes instructions that directly create new nodes, or sequences of nodes, atomic values, 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.7 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.7.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.1 Setting the Type Annotation for Literal Result Elements

The attributes xsl:type and xsl:validation may be used on a literal result element to invoke validation of the contents of the element against a type definition or element declaration in a schema, and to determine the type annotation that the new element node will carry. These attributes also affect the type annotation carried by any elements and attributes that have the new element node as an ancestor. These two attributes are both optional, and if one is specified then the other must be omitted.

The value of the xsl:validation attribute, if present, must be one of the values strict, lax, preserve, or strip. The value of the xsl:type attribute, if present, must be an EQName identifying a type definition that is present in the in-scope schema components for the stylesheet. Neither attribute may be specified as an attribute value template. The effect of these attributes is described in 25.4 Validation.

11.1.2 Attribute Nodes for Literal Result Elements

Attribute nodes for a literal result element may be created by including xsl:attribute instructions within the sequence constructor. Additionally, attribute nodes are created corresponding to the attributes of the literal result element in the stylesheet, and as a result of expanding the xsl:use-attribute-sets attribute of the literal result element, if present.

The sequence that is used to construct the content of the literal result element (as described in 5.7.1 Constructing Complex Content) is the concatenation of the following four sequences, in order:

  1. The sequence of namespace nodes produced as described in 11.1.3 Namespace Nodes for Literal Result Elements.

  2. The sequence of attribute nodes produced by expanding the xsl:use-attribute-sets attribute (if present) following the rules given in 10.2 Named Attribute Sets

  3. The attributes produced by processing the attributes of the literal result element itself, other than attributes in the XSLT namespace. The way these are processed is described below.

  4. The sequence produced by evaluating the contained sequence constructor, if the element is not empty.

Note:

The significance of this order is that an attribute produced by an xsl:attribute, xsl:copy, or xsl:copy-of instruction in the content of the literal result element takes precedence over an attribute produced by expanding an attribute of the literal result element itself, which in turn takes precedence over an attribute produced by expanding the xsl:use-attribute-sets attribute. This is because of the rules in 5.7.1 Constructing Complex Content, which specify that when two or more attributes in the sequence have the same name, all but the last of the duplicates are discarded.

Although the above rules place namespace nodes before attributes, this is not strictly necessary, because the rules in 5.7.1 Constructing Complex Content allow the namespaces and attributes to appear in any order so long as both come before other kinds of node. The order of namespace nodes and attribute nodes in the sequence has no effect on the relative position of the nodes in document order once they are added to a tree.

Each attribute of the literal result element, other than an attribute in the XSLT namespace, is processed to produce an attribute for the element in the result tree.

The value of such an attribute is interpreted as an attribute value template: it can therefore contain expressions contained in curly brackets ({}). The new attribute node will have the same expanded QName (that is, the same namespace URI, local name, and namespace prefix) as the attribute in the stylesheet tree, and its string value will be the same as the effective value of the attribute in the stylesheet tree. The type annotation on the attribute will initially be xs:untypedAtomic, and the typed value of the attribute node will be the same as its string value.

Note:

The eventual type annotation of the attribute in the result tree depends on the xsl:validation and xsl:type attributes of the parent literal result element, and on the instructions used to create its ancestor elements. If the xsl:validation attribute is set to preserve or strip, the type annotation will be xs:untypedAtomic, and the typed value of the attribute node will be the same as its string value. If the xsl:validation attribute is set to strict or lax, or if the xsl:type attribute is used, the type annotation on the attribute will be set as a result of the schema validation process applied to the parent element. If neither attribute is present, the type annotation on the attribute will be xs:untypedAtomic.

If the name of a constructed attribute is xml:id, the processor must perform attribute value normalization by effectively applying the normalize-spaceFO30 function to the value of the attribute, and the resulting attribute node must be given the is-id property.

Note:

If the attribute name is xml:space, it is not an error when the value is something other than default or preserve. Although the XML specification states that other values are erroneous, a document containing such values is well-formed; if erroneous values are to be rejected, schema validation should be used.

Note:

The xml:base, xml:lang, xml:space, and xml:id attributes have two effects in XSLT. They behave as standard XSLT attributes, which means for example that if they appear on a literal result element, they will be copied to the result tree in the same way as any other attribute. In addition, they have their standard meaning as defined in the core XML specifications. Thus, an xml:base attribute in the stylesheet affects the base URI of the element on which it appears, and an xml:space attribute affects the interpretation of whitespace text nodes within that element. One consequence of this is that it is inadvisable to write these attributes as attribute value templates: although an XSLT processor will understand this notation, the XML parser will not. See also 11.1.4 Namespace Aliasing which describes how to use xsl:namespace-alias with these attributes.

The same is true of the schema-defined attributes xsi:type, xsi:nil, xsi:noNamespaceSchemaLocation, and xsi:schemaLocation. If the stylesheet is processed by a schema processor, these attributes will be recognized and interpreted by the schema processor, but in addition the XSLT processor treats them like any other attribute on a literal result element: that is, their effective value (after expanding attribute value templates) is copied to the result tree in the same way as any other attribute. If the result tree is validated, the copied attributes will again be recognized and interpreted by the schema processor.

None of these attributes will be generated in the result tree unless the stylesheet writes them to the result tree explicitly, in the same way as any other attribute.

[ERR XTSE0805] It is a static error if an attribute on a literal result element is in the XSLT namespace, unless it is one of the attributes explicitly defined in this specification.

Note:

If there is a need to create attributes in the XSLT namespace, this can be achieved using xsl:attribute, or by means of the xsl:namespace-alias declaration.

11.1.3 Namespace Nodes for Literal Result Elements

The created element node will have a copy of the namespace nodes that were present on the element node in the stylesheet tree with the exception of any namespace node whose string value is designated as an excluded namespace. Special considerations apply to aliased namespaces: see 11.1.4 Namespace Aliasing.

The following namespaces are designated as excluded namespaces:

  • The XSLT namespace URI (http://www.w3.org/1999/XSL/Transform)

  • A namespace URI declared as an extension namespace (see 24.2 Extension Instructions)

  • A namespace URI designated by using an [xsl:]exclude-result-prefixes attribute either on the literal result element itself or on an ancestor element. The attribute must be in the XSLT namespace only if its parent element is not in the XSLT namespace.

    The value of the attribute is either #all, or a whitespace-separated list of tokens, each of which is either a namespace prefix or #default. The namespace bound to each of the prefixes is designated as an excluded namespace.

    [ERR XTSE0808] It is a static error if a namespace prefix is used within the [xsl:]exclude-result-prefixes attribute and there is no namespace binding in scope for that prefix.

    The default namespace of the parent element of the [xsl:]exclude-result-prefixes attribute (see Section 6.2 Element Nodes DM30) may be designated as an excluded namespace by including #default in the list of namespace prefixes.

    [ERR XTSE0809] It is a static error if the value #default is used within the [xsl:]exclude-result-prefixes attribute and the parent element of the [xsl:]exclude-result-prefixes attribute has no default namespace.

    The value #all indicates that all namespaces that are in scope for the stylesheet element that is the parent of the [xsl:]exclude-result-prefixes attribute are designated as excluded namespaces.

    The designation of a namespace as an excluded namespace is effective within the subtree of the stylesheet module rooted at the element bearing the [xsl:]exclude-result-prefixes attribute; a subtree rooted at an xsl:stylesheet element does not include any stylesheet modules imported or included by children of that xsl:stylesheet element.

The excluded namespaces, as described above, only affect namespace nodes copied from the stylesheet when processing a literal result element. There is no guarantee that an excluded namespace will not appear on the result tree for some other reason. Namespace nodes are also written to the result tree as part of the process of namespace fixup (see 5.7.3 Namespace Fixup), or as the result of instructions such as xsl:copy and xsl:element.

Note:

When a stylesheet uses a namespace declaration only for the purposes of addressing a source tree, specifying the prefix in the [xsl:]exclude-result-prefixes attribute will avoid superfluous namespace declarations in the serialized result tree. The attribute is also useful to prevent namespaces used solely for the naming of stylesheet functions or extension functions from appearing in the serialized result tree.

Example: Excluding Namespaces from the Result Tree

Consider the following stylesheet:

<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:a="a.uri"
  xmlns:b="b.uri"
  exclude-result-prefixes="#all">
  
<xsl:template match="/">
  <foo xmlns:c="c.uri" xmlns:d="d.uri" xmlns:a2="a.uri" 
       xsl:exclude-result-prefixes="c"/>
</xsl:template>

</xsl:stylesheet>

The result of this stylesheet will be:

<foo xmlns:d="d.uri"/>

The namespaces a.uri and b.uri are excluded by virtue of the exclude-result-prefixes attribute on the xsl:stylesheet element, and the namespace c.uri is excluded by virtue of the xsl:exclude-result-prefixes attribute on the foo element. The setting #all does not affect the namespace d.uri because d.uri is not an in-scope namespace for the xsl:stylesheet element. The element in the result tree does not have a namespace node corresponding to xmlns:a2="a.uri" because the effect of exclude-result-prefixes is to designate the namespace URI a.uri as an excluded namespace, irrespective of how many prefixes are bound to this namespace URI.

If the stylesheet is changed so that the literal result element has an attribute b:bar="3", then the element in the result tree will typically have a namespace declaration xmlns:b="b.uri" (the processor may choose a different namespace prefix if this is necessary to avoid conflicts). The exclude-result-prefixes attribute makes b.uri an excluded namespace, so the namespace node is not automatically copied from the stylesheet, but the presence of an attribute whose name is in the namespace b.uri forces the namespace fixup process (see 5.7.3 Namespace Fixup) to introduce a namespace node for this namespace.

A literal result element may have an optional xsl:inherit-namespaces attribute, with the value yes or no. The default value is yes. If the value is set to yes, or is omitted, then the namespace nodes created for the newly constructed element are copied to the children and descendants of the newly constructed element, as described in 5.7.1 Constructing Complex Content. If the value is set to no, then these namespace nodes are not automatically copied to the children. This may result in namespace undeclarations (such as xmlns="" or, in the case of XML 1.1, xmlns:p="") appearing on the child elements when they are serialized.

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.

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.

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

11.2 Creating Element Nodes Using xsl:element

<!-- Category: instruction -->
<xsl:element
  name = { qname }
  namespace? = { uri }
  inherit-namespaces? = boolean
  use-attribute-sets? = eqnames
  type? = eqname
  validation? = "strict" | "lax" | "preserve" | "strip" >
  <!-- Content: sequence-constructor -->
</xsl:element>

The xsl:element instruction allows an element to be created with a computed name. The expanded QName of the element to be created is specified by a required name attribute and an optional namespace attribute.

The result of evaluating the xsl:element instruction, in usual circumstances, is the newly constructed element node.

11.2.1 The Content of the Constructed Element Node

The content of the xsl:element instruction is a sequence constructor for the children, attributes, and namespaces of the created element. The sequence obtained by evaluating this sequence constructor (see 5.7 Sequence Constructors) is used to construct the content of the element, as described in 5.7.1 Constructing Complex Content.

The xsl:element element may have a use-attribute-sets attribute, whose value is a whitespace-separated list of QNames that identify xsl:attribute-set declarations. If this attribute is present, it is expanded as described in 10.2 Named Attribute Sets to produce a sequence of attribute nodes. This sequence is prepended to the sequence produced as a result of evaluating the sequence constructor, as described in 5.7.1 Constructing Complex Content.

11.2.2 The Name of the Constructed Element Node

The name attribute is interpreted as an attribute value template, whose effective value must be a lexical QName.

[ERR XTDE0820] It is a dynamic error if the effective value of the name attribute is not a lexical QName.

[ERR XTDE0830] In the case of an xsl:element instruction with no namespace attribute, it is a dynamic error if the effective value of the name attribute is a lexical QName whose prefix is not declared in an in-scope namespace declaration for the xsl:element instruction.

If the namespace attribute is not present then the lexical QName is expanded into an expanded QName using the namespace declarations in effect for the xsl:element element, including any default namespace declaration.

If the namespace attribute is present, then it too is interpreted as an attribute value template. The effective value must be in the lexical space of the xs:anyURI type. If the string is zero-length, then the expanded QName of the element has a null namespace URI. Otherwise, the string is used as the namespace URI of the expanded QName of the element to be created. The local part of the lexical QName specified by the name attribute is used as the local part of the expanded QName of the element to be created.

[ERR XTDE0835] It is a dynamic error if the effective value of the namespace attribute is not in the lexical space of the xs:anyURI datatype or if it is the string http://www.w3.org/2000/xmlns/.

Note:

The XDM data model requires the name of a node to be an instance of xs:QName, and XML Schema defines the namespace part of an xs:QName to be an instance of xs:anyURI. However, the schema specification, and the specifications that it refers to, give implementations some flexibility in how strictly they enforce these constraints.

The prefix of the lexical QName specified in the name attribute (or the absence of a prefix) is copied to the prefix part of the expanded QName representing the name of the new element node. In the event of a conflict a prefix may subsequently be added, changed, or removed during the namespace fixup process (see 5.7.3 Namespace Fixup). The term conflict here means any violation of the constraints defined in [XDM 3.0], for example the use of the same prefix to refer to two different namespaces in the element and in one of its attributes, the use of the prefix xml to refer to a namespace other than the XML namespace, or any use of the prefix xmlns.

11.2.3 Other Properties of the Constructed Element Node

The xsl:element instruction has an optional inherit-namespaces attribute, with the value yes or no. The default value is yes. If the value is set to yes, or is omitted, then the namespace nodes created for the newly constructed element (whether these were copied from those of the source node, or generated as a result of namespace fixup) are copied to the children and descendants of the newly constructed element, as described in 5.7.1 Constructing Complex Content. If the value is set to no, then these namespace nodes are not automatically copied to the children. This may result in namespace undeclarations (such as xmlns="" or, in the case of XML Namespaces 1.1, xmlns:p="") appearing on the child elements when the element is serialized.

The base URI of the new element is copied from the base URI of the xsl:element instruction 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) against the base URI of the xsl:element instruction in the stylesheet. (Note, however, that this is only relevant when creating parentless elements. When the new 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.)

The values of the nilled, is-id, and is-idrefs properties of the new element depend on the type and validation attributes of the xsl:element instruction, as explained in 25.4 Validation.

11.2.4 The Type Annotation of the Constructed Element Node

The optional attributes type and validation may be used on the xsl:element instruction to invoke validation of the contents of the element against a type definition or element declaration in a schema, and to determine the type annotation that the new element node will carry. These attributes also affect the type annotation carried by any elements and attributes that have the new element node as an ancestor. These two attributes are both optional, and if one is specified then the other must be omitted. The permitted values of these attributes and their semantics are described in 25.4 Validation.

Note:

The final type annotation of the element in the result tree also depends on the type and validation attributes of the instructions used to create the ancestors of the element.

11.3 Creating Attribute Nodes Using xsl:attribute

<!-- Category: instruction -->
<xsl:attribute
  name = { qname }
  namespace? = { uri }
  select? = expression
  separator? = { string }
  type? = eqname
  validation? = "strict" | "lax" | "preserve" | "strip" >
  <!-- Content: sequence-constructor -->
</xsl:attribute>

The xsl:attribute element can be used to add attributes to result elements whether created by literal result elements in the stylesheet or by instructions such as xsl:element or xsl:copy. The expanded QName of the attribute to be created is specified by a required name attribute and an optional namespace attribute. Except in error cases, the result of evaluating an xsl:attribute instruction is the newly constructed attribute node.

The string value of the new attribute node may be defined either by using the select attribute, or by the sequence constructor that forms the content of the xsl:attribute element. These are mutually exclusive: if the select attribute is present then the sequence constructor must be empty, and if the sequence constructor is non-empty then the select attribute must be absent. If the select attribute is absent and the sequence constructor is empty, then the string value of the new attribute node will be a zero-length string. The way in which the value is constructed is specified in 5.7.2 Constructing Simple Content.

[ERR XTSE0840] It is a static error if the select attribute of the xsl:attribute element is present unless the element has empty content.

If the separator attribute is present, then the effective value of this attribute is used to separate adjacent items in the result sequence, as described in 5.7.2 Constructing Simple Content. In the absence of this attribute, the default separator is a single space (#x20) when the content is specified using the select attribute, or a zero-length string when the content is specified using a sequence constructor.

The name attribute is interpreted as an attribute value template, whose effective value must be a lexical QName.

[ERR XTDE0850] It is a dynamic error if the effective value of the name attribute is not a lexical QName.

[ERR XTDE0855] In the case of an xsl:attribute instruction with no namespace attribute, it is a dynamic error if the effective value of the name attribute is the string xmlns.

[ERR XTDE0860] In the case of an xsl:attribute instruction with no namespace attribute, it is a dynamic error if the effective value of the name attribute is a lexical QName whose prefix is not declared in an in-scope namespace declaration for the xsl:attribute instruction.

If the namespace attribute is not present, then the lexical QName is expanded into an expanded QName using the namespace declarations in effect for the xsl:attribute element, not including any default namespace declaration.

If the namespace attribute is present, then it too is interpreted as an attribute value template. The effective value must be in the lexical space of the xs:anyURI type. If the string is zero-length, then the expanded QName of the attribute has a null namespace URI. Otherwise, the string is used as the namespace URI of the expanded QName of the attribute to be created. The local part of the lexical QName specified by the name attribute is used as the local part of the expanded QName of the attribute to be created.

[ERR XTDE0865] It is a dynamic error if the effective value of the namespace attribute is not in the lexical space of the xs:anyURI datatype or if it is the string http://www.w3.org/2000/xmlns/.

Note:

The same considerations apply as for elements: [see ERR XTDE0835] in 11.2 Creating Element Nodes Using xsl:element .

The prefix of the lexical QName specified in the name attribute (or the absence of a prefix) is copied to the prefix part of the expanded QName representing the name of the new attribute node. In the event of a conflict this prefix may subsequently be added, changed, or removed during the namespace fixup process (see 5.7.3 Namespace Fixup). If the attribute is in a non-null namespace and no prefix is specified, then the namespace fixup process will invent a prefix. The term conflict here means any violation of the constraints defined in [XDM 3.0], for example the use of the same prefix to refer to two different namespaces in the element and in one of its attributes, the use of the prefix xml to refer to a namespace other than the XML namespace, or any use of the prefix xmlns.

If the name of a constructed attribute is xml:id, the processor must perform attribute value normalization by effectively applying the normalize-spaceFO30 function to the value of the attribute, and the resulting attribute node must be given the is-id property. This applies whether the attribute is constructed using the xsl:attribute instruction or whether it is constructed using an attribute of a literal result element. This does not imply any constraints on the value of the attribute, or on its uniqueness, and it does not affect the type annotation of the attribute, unless the containing document is validated.

Note:

The effect of setting the is-id property is that the parent element can be located within the containing document by use of the idFO30 function. In effect, XSLT when constructing a document performs some of the functions of an xml:id processor, as defined in [xml:id]; the other aspects of xml:id processing are performed during validation.

Example: Creating a List-Valued Attribute

The following instruction creates the attribute colors="red green blue":

<xsl:attribute name="colors" select="'red', 'green', 'blue'"/>

 

Example: Namespaces are not Attributes

It is not an error to write:

<xsl:attribute name="xmlns:xsl" 
   namespace="file://some.namespace"
   select="'http://www.w3.org/1999/XSL/Transform'"/>

However, this will not result in the namespace declaration xmlns:xsl="http://www.w3.org/1999/XSL/Transform" being output. Instead, it will produce an attribute node with local name xsl, and with a system-allocated namespace prefix mapped to the namespace URI file://some.namespace. This is because the namespace fixup process is not allowed to use xmlns as the name of a namespace node.

As described in 5.7.1 Constructing Complex Content, in a sequence that is used to construct the content of an element, any attribute nodes must appear in the sequence before any element, text, comment, or processing instruction nodes. Where the sequence contains two or more attribute nodes with the same expanded QName, the one that comes last is the only one that takes effect.

Note:

If a collection of attributes is generated repeatedly, this can be done conveniently by using named attribute sets: see 10.2 Named Attribute Sets

11.3.1 Setting the Type Annotation for a Constructed Attribute Node

The optional attributes type and validation may be used on the xsl:attribute instruction to invoke validation of the contents of the attribute against a type definition or attribute declaration in a schema, and to determine the type annotation that the new attribute node will carry. These two attributes are both optional, and if one is specified then the other must be omitted. The permitted values of these attributes and their semantics are described in 25.4 Validation.

The process of validation also determines the values of the is-id and is-idrefs properties on the new attribute node.

Note:

The final type annotation of the attribute in the result tree also depends on the type and validation attributes of the instructions used to create the ancestors of the attribute.

11.4 Creating Text Nodes

This section describes three different ways of creating text nodes: by means of literal text nodes in the stylesheet, or by using the xsl:text and xsl:value-of instructions. It is also possible to create text nodes using the xsl:number instruction described in 12 Numbering.

If and when the sequence that results from evaluating a sequence constructor is used to form the content of a node, as described in 5.7.2 Constructing Simple Content and 5.7.1 Constructing Complex Content, adjacent text nodes in the sequence are merged. Within the sequence itself, however, they exist as distinct nodes.

Example: A Sequence of Text Nodes

The following function returns a sequence of three text nodes:

<xsl:function name="f:wrap">
  <xsl:param name="s"/>
  <xsl:text>(</xsl:text>
  <xsl:value-of select="$s"/>
  <xsl:text>)</xsl:text>
</xsl:function>

When this function is called as follows:

<xsl:value-of select="f:wrap('---')"/>

the result is:

(---)

No additional spaces are inserted, because the calling xsl:value-of instruction merges adjacent text nodes before atomizing the sequence. However, the result of the instruction:

<xsl:value-of select="data(f:wrap('---'))"/>

is:

( --- )

because in this case the three text nodes are atomized to form three strings, and spaces are inserted between adjacent strings.

It is possible to construct text nodes whose string value is zero-length. A zero-length text node, when atomized, produces a zero-length string. However, zero-length text nodes are ignored when they appear in a sequence that is used to form the content of a node, as described in 5.7.1 Constructing Complex Content and 5.7.2 Constructing Simple Content.

11.4.1 Literal Text Nodes

A sequence constructor can contain text nodes. Each text node in a sequence constructor remaining after whitespace text nodes have been stripped as specified in 4.3 Stripping Whitespace from the Stylesheet will construct a new text node with the same string value. The resulting text node is added to the result of the containing sequence constructor.

Text is processed at the tree level. Thus, markup of &lt; in a template will be represented in the stylesheet tree by a text node that includes the character <. This will create a text node in the result tree that contains a < character, which will be represented by the markup &lt; (or an equivalent character reference) when the result tree is serialized as an XML document, unless otherwise specified using character maps (see 26.1 Character Maps) or disable-output-escaping (see 26.2 Disabling Output Escaping).

11.4.2 Creating Text Nodes Using xsl:text

<!-- Category: instruction -->
<xsl:text
  [disable-output-escaping]? = boolean >
  <!-- Content: #PCDATA -->
</xsl:text>

The xsl:text element is evaluated to construct a new text node.

If the element or one of its ancestors has an [xsl:]expand-text attribute, and the nearest ancestor with such an attribute has the value yes, then any unescaped curly brackets in the value of the element indicate the presence of text value templates, which are expanded as described in 5.6.2 Text Value Templates.

In the absence of such an attribute, or if the effective value is no, the content of the xsl:text element is a single text node whose value forms the string value of the new text node. An xsl:text element may be empty, in which case the result of evaluating the instruction is a text node whose string value is the zero-length string.

The result of evaluating an xsl:text instruction is the newly constructed text node.

A text node that is an immediate child of an xsl:text instruction will not be stripped from the stylesheet tree, even if it consists entirely of whitespace (see 4.4.2 Stripping Whitespace from a Source Tree).

For the effect of the deprecated disable-output-escaping attribute, see 26.2 Disabling Output Escaping

Note:

It is not always necessary to use the xsl:text instruction to write text nodes to the result tree. Literal text can be written to the result tree by including it anywhere in a sequence constructor, while computed text can be output using the xsl:value-of instruction. The principal reason for using xsl:text is that it offers improved control over whitespace handling.

11.4.3 Generating Text with xsl:value-of

Within a sequence constructor, the xsl:value-of instruction can be used to generate computed text nodes. The xsl:value-of instruction computes the text using an expression that is specified as the value of the select attribute, or by means of contained instructions. This might, for example, extract text from a source tree or insert the value of a variable.

<!-- Category: instruction -->
<xsl:value-of
  select? = expression
  separator? = { string }
  [disable-output-escaping]? = boolean >
  <!-- Content: sequence-constructor -->
</xsl:value-of>

The xsl:value-of instruction is evaluated to construct a new text node; the result of the instruction is the newly constructed text node.

The string value of the new text node may be defined either by using the select attribute, or by the sequence constructor (see 5.7 Sequence Constructors) that forms the content of the xsl:value-of element. These are mutually exclusive: if the select attribute is present then the sequence constructor must be empty, and if the sequence constructor is non-empty then the select attribute must be absent. If the select attribute is absent and the sequence constructor is empty, then the result of the instruction is a text node whose string value is zero-length. The way in which the value is constructed is specified in 5.7.2 Constructing Simple Content.

[ERR XTSE0870] It is a static error if the select attribute of the xsl:value-of element is present when the content of the element is non-empty.

If the separator attribute is present, then the effective value of this attribute is used to separate adjacent items in the result sequence, as described in 5.7.2 Constructing Simple Content. In the absence of this attribute, the default separator is a single space (#x20) when the content is specified using the select attribute, or a zero-length string when the content is specified using a sequence constructor.

Special rules apply when the instruction is processed with XSLT 1.0 behavior. If no separator attribute is present, and if the select attribute is present, then all items in the atomized result sequence other than the first are ignored.

Example: Generating a List with Separators

The instruction:

<x><xsl:value-of select="1 to 4" separator="|"/></x>

produces the output:

<x>1|2|3|4</x>

Note:

The xsl:copy-of element can be used to copy a sequence of nodes to the result tree without atomization. See 11.9.2 Deep Copy.

For the effect of the deprecated disable-output-escaping attribute, see 26.2 Disabling Output Escaping

11.5 Creating Document Nodes

<!-- Category: instruction -->
<xsl:document
  validation? = "strict" | "lax" | "preserve" | "strip"
  type? = eqname >
  <!-- Content: sequence-constructor -->
</xsl:document>

The xsl:document instruction is used to create a new document node. The content of the xsl:document element is a sequence constructor for the children of the new document node. A document node is created, and the sequence obtained by evaluating the sequence constructor is used to construct the content of the document, as described in 5.7.1 Constructing Complex Content.

Except in error situations, the result of evaluating the xsl:document instruction is a single node, the newly constructed document node.

Note:

The new document is not serialized. To construct a document that is to form a final result rather than an intermediate result, use the xsl:result-document instruction described in 25.1 Creating Secondary Results.

The optional attributes type and validation may be used on the xsl:document instruction to validate the contents of the new document, and to determine the type annotation that elements and attributes within the result tree will carry. The permitted values and their semantics are described in 25.4.2 Validating Document Nodes.

The base URI of the new document node is taken from the base URI of the xsl:document instruction.

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

Example: Checking Uniqueness Constraints in a Temporary Tree

The following example creates a temporary tree held in a variable. The use of an enclosed xsl:document instruction ensures that uniqueness constraints defined in the schema for the relevant elements are checked.

<xsl:variable name="tree" as="document-node()">
  <xsl:document validation="strict">
    <xsl:apply-templates/>
  </xsl:document>
</xsl:variable>

11.6 Creating Processing Instructions

<!-- Category: instruction -->
<xsl:processing-instruction
  name = { ncname }
  select? = expression >
  <!-- Content: sequence-constructor -->
</xsl:processing-instruction>

The xsl:processing-instruction element is evaluated to create a processing instruction node.

The xsl:processing-instruction element has a required name attribute that specifies the name of the processing instruction node. The value of the name attribute is interpreted as an attribute value template.

The string value of the new processing-instruction node may be defined either by using the select attribute, or by the sequence constructor that forms the content of the xsl:processing-instruction element. These are mutually exclusive: if the select attribute is present then the sequence constructor must be empty, and if the sequence constructor is non-empty then the select attribute must be absent. If the select attribute is absent and the sequence constructor is empty, then the string value of the new processing-instruction node will be a zero-length string. The way in which the value is constructed is specified in 5.7.2 Constructing Simple Content.

[ERR XTSE0880] It is a static error if the select attribute of the xsl:processing-instruction element is present unless the element has empty content.

Except in error situations, the result of evaluating the xsl:processing-instruction instruction is a single node, the newly constructed processing instruction node.

Example: Creating a Processing Instruction

This instruction:

<xsl:processing-instruction name="xml-stylesheet"
  select="('href=&quot;book.css&quot;', 'type=&quot;text/css&quot;')"/>

creates the processing instruction

<?xml-stylesheet href="book.css" type="text/css"?>

Note that the xml-stylesheet processing instruction contains pseudo-attributes in the form name="value". Although these have the same textual form as attributes in an element start tag, they are not represented as XDM attribute nodes, and cannot therefore be constructed using xsl:attribute instructions.

[ERR XTDE0890] It is a dynamic error if the effective value of the name attribute is not both an NCNameNames and a PITargetXML.

Note:

Because these rules disallow the name xml, the xsl:processing-instruction cannot be used to output an XML declaration. The xsl:output declaration should be used to control this instead (see 26 Serialization).

If the result of evaluating the content of the xsl:processing-instruction contains the string ?>, this string is modified by inserting a space between the ? and > characters.

The base URI of the new processing-instruction is copied from the base URI of the xsl:processing-instruction element in the stylesheet. (Note, however, that this is only relevant when creating a parentless processing instruction. When the new processing instruction 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.7 Creating Namespace Nodes

<!-- Category: instruction -->
<xsl:namespace
  name = { ncname }
  select? = expression >
  <!-- Content: sequence-constructor -->
</xsl:namespace>

The xsl:namespace element is evaluated to create a namespace node. Except in error situations, the result of evaluating the xsl:namespace instruction is a single node, the newly constructed namespace node.

The xsl:namespace element has a required name attribute that specifies the name of the namespace node (that is, the namespace prefix). The value of the name attribute is interpreted as an attribute value template. If the effective value of the name attribute is a zero-length string, a namespace node is added for the default namespace.

The string value of the new namespace node (that is, the namespace URI) may be defined either by using the select attribute, or by the sequence constructor that forms the content of the xsl:namespace element. These are mutually exclusive: if the select attribute is present then the sequence constructor must be empty, and if the sequence constructor is non-empty then the select attribute must be absent. Since the string value of a namespace node cannot be a zero-length string, either a select attribute or a non-empty sequence constructor must be present. The way in which the value is constructed is specified in 5.7.2 Constructing Simple Content.

[ERR XTDE0905] It is a dynamic error if the string value of the new namespace node is not valid in the lexical space of the datatype xs:anyURI, or if it is the string http://www.w3.org/2000/xmlns/.

[ERR XTSE0910] It is a static error if the select attribute of the xsl:namespace element is present when the element has content other than one or more xsl:fallback instructions, or if the select attribute is absent when the element has empty content.

Note the restrictions described in 5.7.1 Constructing Complex Content for the position of a namespace node relative to other nodes in the node sequence returned by a sequence constructor.

Example: Constructing a QName-Valued Attribute

This literal result element:

<data xsi:type="xs:integer" 
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <xsl:namespace name="xs" 
                 select="'http://www.w3.org/2001/XMLSchema'"/>
  <xsl:text>42</xsl:text>
</data>

would typically cause the output document to contain the element:

<data xsi:type="xs:integer"
     xmlns:xs="http://www.w3.org/2001/XMLSchema"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">42</data>

In this case, the element is constructed using a literal result element, and the namespace xmlns:xs="http://www.w3.org/2001/XMLSchema" could therefore have been added to the result tree simply by declaring it as one of the in-scope namespaces in the stylesheet. In practice, the xsl:namespace instruction is more likely to be useful in situations where the element is constructed using an xsl:element instruction, which does not copy all the in-scope namespaces from the stylesheet.

[ERR XTDE0920] It is a dynamic error if the effective value of the name attribute is neither a zero-length string nor an NCNameNames, or if it is xmlns.

[ERR XTDE0925] It is a dynamic error if the xsl:namespace instruction generates a namespace node whose name is xml and whose string value is not http://www.w3.org/XML/1998/namespace, or a namespace node whose string value is http://www.w3.org/XML/1998/namespace and whose name is not xml.

[ERR XTDE0930] It is a dynamic error if evaluating the select attribute or the contained sequence constructor of an xsl:namespace instruction results in a zero-length string.

For details of other error conditions that may arise, see 5.7 Sequence Constructors.

Note:

It is rarely necessary to use xsl:namespace to create a namespace node in the result tree; in most circumstances, the required namespace nodes will be created automatically, as a side-effect of writing elements or attributes that use the namespace. An example where xsl:namespace is needed is a situation where the required namespace is used only within attribute values in the result document, not in element or attribute names; especially where the required namespace prefix or namespace URI is computed at run-time and is not present in either the source document or the stylesheet.

Adding a namespace node to the result tree will never change the expanded QName of any element or attribute node in the result tree: that is, it will never change the namespace URI of an element or attribute. It might, however, constrain the choice of prefixes when namespace fixup is performed.

Namespace prefixes for element and attribute names are initially established by the rules of the instruction that creates the element or attribute node, and in the event of conflicts, they may be changed by the namespace fixup process described in 5.7.3 Namespace Fixup. The fixup process ensures that an element has in-scope namespace nodes for the namespace URIs used in the element name and in its attribute names, and the serializer will typically use these namespace nodes to determine the prefix to use in the serialized output. The fixup process cannot generate namespace nodes that are inconsistent with those already present in the tree. This means that it is not possible for the processor to decide the prefix to use for an element or for any of its attributes until all the namespace nodes for the element have been added.

If a namespace prefix is mapped to a particular namespace URI using the xsl:namespace instruction, or by using xsl:copy or xsl:copy-of to copy a namespace node, this prevents the namespace fixup process (and hence the serializer) from using the same prefix for a different namespace URI on the same element.

Example: Conflicting Namespace Prefixes

Given the instruction:

<xsl:element name="p:item" 
                 xmlns:p="http://www.example.com/p">
  <xsl:namespace name="p">http://www.example.com/q</xsl:namespace>
</xsl:element>

a possible serialization of the result tree is:

<ns0:item 
    xmlns:ns0="http://www.example.com/p" 
    xmlns:p="http://www.example.com/q"/>

The processor must invent a namespace prefix for the URI p.uri; it cannot use the prefix p because that prefix has been explicitly associated with a different URI.

Note:

The xsl:namespace instruction cannot be used to generate a namespace undeclaration of the form xmlns="" (nor the new forms of namespace undeclaration permitted in [Namespaces in XML 1.1]). Namespace undeclarations are generated automatically by the serializer if undeclare-prefixes="yes" is specified on xsl:output, whenever a parent element has a namespace node for the default namespace prefix, and a child element has no namespace node for that prefix.

11.8 Creating Comments

<!-- Category: instruction -->
<xsl:comment
  select? = expression >
  <!-- Content: sequence-constructor -->
</xsl:comment>

The xsl:comment element is evaluated to construct a new comment node. Except in error cases, the result of evaluating the xsl:comment instruction is a single node, the newly constructed comment node.

The string value of the new comment node may be defined either by using the select attribute, or by the sequence constructor that forms the content of the xsl:comment element. These are mutually exclusive: if the select attribute is present then the sequence constructor must be empty, and if the sequence constructor is non-empty then the select attribute must be absent. If the select attribute is absent and the sequence constructor is empty, then the string value of the new comment node will be a zero-length string. The way in which the value is constructed is specified in 5.7.2 Constructing Simple Content.

[ERR XTSE0940] It is a static error if the select attribute of the xsl:comment element is present unless the element has empty content.

Example: Generating a Comment Node

For example, this

<xsl:comment>This file is automatically generated. Do not edit!</xsl:comment>

would create the comment

<!--This file is automatically generated. Do not edit!-->

In the generated comment node, the processor must insert a space after any occurrence of x2D (hyphen) that is followed by another occurrence of x2D (hyphen) or that ends the comment.

11.9 Copying Nodes

11.9.1 Shallow Copy

<!-- Category: instruction -->
<xsl:copy
  select? = expression
  copy-namespaces? = boolean
  inherit-namespaces? = boolean
  use-attribute-sets? = eqnames
  type? = eqname
  validation? = "strict" | "lax" | "preserve" | "strip" >
  <!-- Content: sequence-constructor -->
</xsl:copy>

The xsl:copy instruction provides a way of copying a selected item. The selected item is the item selected by evaluating the expression in the select attribute if present, or the context item otherwise. If the selected item is a node, evaluating the xsl:copy instruction constructs a copy of the selected node, and the result of the xsl:copy instruction is this newly constructed node. By default, the namespace nodes of the context node are automatically copied as well, but the attributes and children of the node are not automatically copied.

[ERR XTTE0945] It is a type error to use the xsl:copy instruction with no select attribute when the context item is absent.

If the select expression returns an empty sequence, the xsl:copy instruction returns an empty sequence, and the contained sequence constructor is not evaluated.

[ERR XTTE3180] It is a type error if the result of evaluating the select expression is a sequence of more than one item.

When the selected item is an atomic value or function item, the xsl:copy instruction returns this value. The sequence constructor is not evaluated.

When the selected item is an attribute node, text node, comment node, processing instruction node, or namespace node, the xsl:copy instruction returns a new node that is a copy of the context node. The new node will have the same node kind, name, and string value as the context node. In the case of an attribute node, it will also have the same values for the is-id and is-idrefs properties. The sequence constructor is not evaluated.

When the selected item is a document node or element node, the xsl:copy instruction returns a new node that has the same node kind and name as the selected node. The content of the new node is formed by evaluating the sequence constructor contained in the xsl:copy instruction. If the select attribute is present then the sequence constructor is evaluated with the selected item as the singleton focus; otherwise it is evaluated using the context of the xsl:copy instruction unchanged. The sequence obtained by evaluating this sequence constructor is used (after prepending any attribute nodes or namespace nodes as described in the following paragraphs) to construct the content of the document or element node, as described in 5.7.1 Constructing Complex Content.

When the selected item is a document node, the unparsed-entities property of the existing document node is copied to the new document node.

When the selected item is an element or attribute node, the values of the is-id, is-idrefs, and nilled properties of the new element or attribute depend on the values of the validation and type attributes, as defined in 25.4 Validation.

The xsl:copy instruction has an optional use-attribute-sets attribute, whose value is a whitespace-separated list of QNames that identify xsl:attribute-set declarations. This attribute is used only when copying element nodes. This list is expanded as described in 10.2 Named Attribute Sets to produce a sequence of attribute nodes. This sequence is prepended to the sequence produced as a result of evaluating the sequence constructor.

The xsl:copy instruction has an optional copy-namespaces attribute, with the value yes or no. The default value is yes. The attribute is used only when copying element nodes. If the value is set to yes, or is omitted, then all the namespace nodes of the source element are copied as namespace nodes for the result element. These copied namespace nodes are prepended to the sequence produced as a result of evaluating the sequence constructor (it is immaterial whether they come before or after any attribute nodes produced by expanding the use-attribute-sets attribute). If the value is set to no, then the namespace nodes are not copied. However, namespace nodes will still be added to the result element as required by the namespace fixup process: see 5.7.3 Namespace Fixup.

The xsl:copy instruction has an optional inherit-namespaces attribute, with the value yes or no. The default value is yes. The attribute is used only when copying element nodes. If the value is set to yes, or is omitted, then the namespace nodes created for the newly constructed element (whether these were copied from those of the source node, or generated as a result of namespace fixup) are copied to the children and descendants of the newly constructed element, as described in 5.7.1 Constructing Complex Content. If the value is set to no, then these namespace nodes are not automatically copied to the children. This may result in namespace undeclarations (such as xmlns="" or, in the case of XML Namespaces 1.1, xmlns:p="") appearing on the child elements when a final result tree is serialized.

[ERR XTTE0950] It is a type error to use the xsl:copy or xsl:copy-of instruction to copy a node that has namespace-sensitive content if the copy-namespaces attribute has the value no and its explicit or implicit validation attribute has the value preserve. It is also a type error if either of these instructions (with validation="preserve") is used to copy an attribute having namespace-sensitive content, unless the parent element is also copied. A node has namespace-sensitive content if its typed value contains an item of type xs:QName or xs:NOTATION or a type derived therefrom. The reason this is an error is because the validity of the content depends on the namespace context being preserved.

Note:

When attribute nodes are copied, whether with xsl:copy or with xsl:copy-of, the processor does not automatically copy any associated namespace information. The namespace used in the attribute name itself will be declared by virtue of the namespace fixup process (see 5.7.3 Namespace Fixup) when the attribute is added to an element in the result tree, but if namespace prefixes are used in the content of the attribute (for example, if the value of the attribute is an XPath expression) then it is the responsibility of the stylesheet author to ensure that suitable namespace nodes are added to the result tree. This can be achieved by copying the namespace nodes using xsl:copy, or by generating them using xsl:namespace.

The optional attributes type and validation may be used on the xsl:copy instruction to validate the contents of an element, attribute or document node against a type definition, element declaration, or attribute declaration in a schema, and thus to determine the type annotation that the new copy of an element or attribute node will carry. These attributes are ignored when copying an item that is not an element, attribute or document node. When the node being copied is an element or document node, these attributes also affect the type annotation carried by any elements and attributes that have the copied element or document node as an ancestor. These two attributes are both optional, and if one is specified then the other must be omitted. The permitted values of these attributes and their semantics are described in 25.4 Validation.

Note:

The final type annotation of the node in the result tree also depends on the type and validation attributes of the instructions used to create the ancestors of the node.

When a node is copied, its base URI is copied, except when the result of the xsl:copy instruction is an element node having an xml:base attribute, in which case the base URI of the new node is taken as the value of its xml:base attribute, resolved if it is relative against the base URI of the xsl:copy instruction.

When an xml:id attribute is copied, using either the xsl:copy or xsl:copy-of instruction, it is implementation-defined whether the value of the attribute is subjected to attribute value normalization (that is, effectively applying the normalize-spaceFO30 function).

Note:

In most cases the value will already have been subjected to attribute value normalization on the source tree, but if this processing has not been performed on the source tree, it is not an error for it to be performed on the result tree.

11.9.2 Deep Copy

<!-- Category: instruction -->
<xsl:copy-of
  select = expression
  copy-accumulators? = boolean
  copy-namespaces? = boolean
  type? = eqname
  validation? = "strict" | "lax" | "preserve" | "strip" />

The xsl:copy-of instruction can be used to construct a copy of a sequence of nodes, atomic values, and/or function items with each new node containing copies of all the children, attributes, and (by default) namespaces of the original node, recursively. The result of evaluating the instruction is a sequence of items corresponding one-to-one with the supplied sequence, and retaining its order.

The required select attribute contains an expression, whose value may be any sequence of nodes, atomic values, and/or function items. The items in this sequence are processed as follows:

  • If the item is an element node, a new element is constructed and appended to the result sequence. The new element will have the same expanded QName as the original, and it will have deep copies of the attribute nodes and children of the element node.

    The new element will also have namespace nodes copied from the original element node, unless they are excluded by specifying copy-namespaces="no". If this attribute is omitted, or takes the value yes, then all the namespace nodes of the original element are copied to the new element. If it takes the value no, then none of the namespace nodes are copied: however, namespace nodes will still be created in the result tree as required by the namespace fixup process: see 5.7.3 Namespace Fixup. This attribute affects all elements copied by this instruction: both elements selected directly by the select expression, and elements that are descendants of nodes selected by the select expression.

    The values of the is-id, is-idrefs, and nilled properties of the new element depend on the values of the validation and type attributes, as defined in 25.4 Validation.

  • If the item is a document node, the instruction adds a new document node to the result sequence; the children of this document node will be one-to-one copies of the children of the original document node (each copied according to the rules for its own node kind). The unparsed-entities property of the original document node is copied to the new document node.

  • If the item is an attribute or namespace node, or a text node, a comment, or a processing instruction, the same rules apply as with xsl:copy (see 11.9.1 Shallow Copy).

  • If the item is an atomic value or a function item, the value is appended to the result sequence, as with xsl:sequence.

The optional attributes type and validation may be used on the xsl:copy-of instruction to validate the contents of an element, attribute or document node against a type definition, element declaration, or attribute declaration in a schema and thus to determine the type annotation that the new copy of an element or attribute node will carry. These attributes are applied individually to each element, attribute, and document node that is selected by the expression in the select attribute. These attributes are ignored when copying an item that is not an element, attribute or document node.

The specified type and validation apply directly only to elements, attributes and document nodes created as copies of nodes actually selected by the select expression, they do not apply to nodes that are implicitly copied because they have selected nodes as an ancestor. However, these attributes do indirectly affect the type annotation carried by such implicitly copied nodes, as a consequence of the validation process.

These two attributes are both optional, and if one is specified then the other must be omitted. The permitted values of these attributes and their semantics are described in 25.4 Validation.

Errors may occur when copying namespace-sensitive elements or attributes using validation="preserve". [see ERR XTTE0950].

If removal of namespaces is requested using copy-namespaces="no", then any validation that is requested is applied to the tree that remains after the relevant namespaces have been removed. This will cause validation to fail if there is namespace-sensitive content that depends on the presence of the removed namespaces.

The base URI of a node is copied, except in the case of an element node having an xml:base attribute, in which case the base URI of the new node is taken as the value of the xml:base attribute, resolved if it is relative against the base URI of the xsl:copy-of instruction. If the copied node is subsequently attached as a child to a new element or document node, the final copy of the node inherits its base URI from its parent node, unless this is overridden using an xml:base attribute.

The effect of the copy-accumulators attribute is described in 18.2.2 Applicability of Accumulators.

11.10 Constructing Sequences

<!-- Category: instruction -->
<xsl:sequence
  select? = expression >
  <!-- Content: sequence-constructor -->
</xsl:sequence>

The xsl:sequence instruction may be used within a sequence constructor to construct a sequence of nodes, atomic values, and/or function items. This sequence is returned as the result of the instruction. Unlike most other instructions, xsl:sequence can return a sequence containing existing nodes, rather than constructing new nodes. When xsl:sequence is used to select atomic values or function items, the effect is very similar to the xsl:copy-of instruction.

The items comprising the result sequence are evaluated either using the select attribute, or using the contained sequence constructor. These are mutually exclusive; if the instruction has a select attribute, then it must have no children other than xsl:fallback instructions. If there is no select attribute and no contained sequence constructor, the result is an empty sequence.

[ERR XTSE3185] It is a static error if the select attribute of xsl:sequence is present and the instruction has children other than xsl:fallback.

Any contained xsl:fallback instructions are ignored by an XSLT 2.0 or 3.0 processor, but can be used to define fallback behavior for an XSLT 1.0 processor running in forwards compatibility mode.

Example: Constructing a Sequence of Integers

The following code:

<xsl:variable name="values" as="xs:integer*">
    <xsl:sequence select="(1,2,3,4)"/>
    <xsl:sequence select="(8,9,10)"/>
</xsl:variable>
<xsl:value-of select="sum($values)"/>

produces the output: 37

 

Example: Using xsl:for-each to Construct a Sequence

The following code constructs a sequence containing the value of the @price attribute for selected elements (which we assume to be typed as xs:decimal), or a computed price for those elements that have no @price attribute. It then returns the average price:

<xsl:variable name="prices" as="xs:decimal*">
  <xsl:for-each select="//product">
    <xsl:choose>
      <xsl:when test="@price">
        <xsl:sequence select="@price"/>
      </xsl:when>
      <xsl:otherwise>
        <xsl:sequence select="@cost * 1.5"/>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:for-each>
</xsl:variable>
<xsl:value-of select="avg($prices)"/>

Note that the existing @price attributes could equally have been added to the $prices sequence using xsl:copy-of or xsl:value-of. However, xsl:copy-of would create a copy of the attribute node, which is not needed in this situation, while xsl:value-of would create a new text node, which then has to be converted to an xs:decimal. Using xsl:sequence, which in this case atomizes the existing attribute node and adds an xs:decimal atomic value to the result sequence, is a more direct way of achieving the same result.

This example could alternatively be solved at the XPath level:

<xsl:value-of select="avg(//product/(+@price, @cost*1.5)[1])"/>

The apparently redundant + operator is there to atomize the attribute value: the expression on the right hand side of the / operator must not return a sequence containing both nodes and non-nodes (atomic values or function items).

Note:

The main use case for allowing xsl:sequence to contain a sequence constructor is to allow the instructions within an xsl:fork element to be divided into groups.

It can also be used to limit the scope of local variables or of standard attributes such as [xsl:]default-collation.