Constructing Nodes

Constructing Elements and Attributes

Most output is literal result elements, with attribute value templates (name="{expr}") for computed values. Computed names need xsl:element and xsl:attribute; xsl:namespace, xsl:comment and xsl:processing-instruction build other node kinds; xsl:copy copies one node, xsl:copy-of a whole subtree; xsl:number numbers nodes. Output is cut after 6 lines:

feed.xsl: constructing every kind of node for a partner feedXML
<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs">
  <xsl:output method="xml" indent="yes"/>
  <xsl:template match="/catalog">
    <xsl:comment select="' ' || count(book) || ' books from ' || header/sender || ' '"/>
    <feed partner="shelfwise">
      <xsl:namespace name="bn" select="'https://booknest.example.com/ns/catalog'"/>
      <xsl:for-each select="book[supply/availability = 'in-stock']">
        <xsl:element name="{if (pages > 400) then 'big-product' else 'product'}">
          <xsl:attribute name="n"><xsl:number/></xsl:attribute>
          <xsl:attribute name="code" select="identifier"/>
          <xsl:copy-of select="title"/>
          <xsl:copy select="contributor"><xsl:value-of select="name"/></xsl:copy>
        </xsl:element>
      </xsl:for-each>
    </feed>
  </xsl:template>
</xsl:stylesheet>
Output
<?xml version="1.0" encoding="UTF-8"?>
<!-- 6 books from BookNest Catalog Service -->
<feed xmlns:bn="https://booknest.example.com/ns/catalog" partner="shelfwise">
   <product n="1" code="BN-0001">
      <title>The Quiet Harbor</title>
      <contributor>Mara Ellison</contributor>

Further down, b2 (428 pages) becomes a big-product, and since xsl:number counts siblings in the source, the product after the sold-out b3 is numbered 4: use position() for output order. exclude-result-prefixes kept xmlns:xs out of the result.


Constructing Nodes

This section covers the instructions used to construct new nodes: <xsl:document>, <xsl:result-document>, <xsl:element>, <xsl:attribute>, <xsl:namespace>, <xsl:comment>, <xsl:processing-instruction>, <xsl:text>, <xsl:sequence> and <xsl:number>. The example below builds a single output element containing an attribute, a namespace declaration, a comment, a processing instruction, a sequence of integers, and a formatted number.
ch06-construct-nodes.xslXML
<?xml version="1.0" encoding="UTF-8"?>
<xsl:transform version="3.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
      xmlns:xs="http://www.w3.org/2001/XMLSchema"
      xmlns:fn="http://www.w3.org/2005/xpath-functions">
   <xsl:template match="/">
      <xsl:text>&#10;</xsl:text>
      <xsl:document>
         <xsl:element name="a">
           <xsl:namespace name="ns"
                                    select="'http://example.com'"/>
           <xsl:attribute name="x" select="division/num2"/>
           <xsl:attribute name="y">10</xsl:attribute>
           <xsl:text>&#10;</xsl:text>
           <xsl:comment>COMMENT</xsl:comment>
           <xsl:processing-instruction name="pi"
                                                   select="'INSTRUCTION'"/>
           <xsl:text>&#10;</xsl:text>
           <xsl:sequence select="(1 to 5)"/>
           <xsl:text>&#10;</xsl:text>
           <xsl:number value="100000000"
                          grouping-separator="," grouping-size="3"/>
           <xsl:text>&#10;</xsl:text>
         </xsl:element>
      </xsl:document>
   </xsl:template>
</xsl:transform>
<xsl:attribute>, <xsl:namespace>, <xsl:comment>, <xsl:processing-instruction>, <xsl:sequence> and <xsl:number> can each carry a select attribute; when this attribute is absent, the value is instead given as content children.

<xsl:attribute> attributes: namespace ({uri}), separator ({string}), type (eqname), validation ("strict" | "lax" | "preserve" | "strip"), on-empty (expression).
<xsl:element> attributes: namespace ({uri}), inherit-namespaces ("yes" | "no"), use-attribute-sets (eqnames), type (eqname), validation ("strict" | "lax" | "preserve" | "strip"), on-empty (expression).
<xsl:number> attributes: select (expression), level ("single" | "multiple" | "any"), count (pattern), from (pattern), format ({string}), lang ({language}), letter-value ({"alphabetic" | "traditional"}), ordinal ({string}), start-at ({integer}).
To construct a document intended to form a final result rather than an intermediate result, use <xsl:result-document> instead of <xsl:document>. It can have the following attributes: format ({eqname}), href ({uri}), validation ("strict" | "lax" | "preserve" | "strip"), type (eqname), method ({"xml" | "html" | "xhtml" | "text" | eqname}), byte-order-mark, cdata-section-elements, doctype-public, doctype-system, encoding, escape-uri-attributes, html-version, include-content-type, indent, item-separator, media-type, normalization-form ({"NFC" | "NFD" | "NFKC" | "NFKD" | "fully-normalized" | "none" | nmtoken}), omit-xml-declaration, parameter-document, standalone ({"yes" | "no" | "omit"}), suppress-indentation, undeclare-prefixes, use-character-maps, output-version ({nmtoken}).