Chapter 4. Elements

This chapter contains an alphabetical reference of the elements in the XSLT namespace (http://www.w3.org/1999/XSL/Transform) that are a part of XSLT 1.0. Some of these elements are instructions; some are top-level elements. Others don’t fall into either category, so we’ll call them “special.”

Tip

The names of XSLT elements in this chapter include the conventional xsl prefix. Of course, any prefix could be used as long as it binds to the XSLT namespace.

Top-Level Elements

A top-level element is an element that occurs as the child of the stylesheet’s document element (either xsl:stylesheet or xsl:transform). Below are all the top-level XSLT elements, listed in alphabetical order:

xsl:attribute-setxsl:output
xsl:decimal-formatxsl:param
xsl:importxsl:preserve-space
xsl:includexsl:strip-space
xsl:keyxsl:template
xsl:namespace-aliasxsl:variable

These elements may occur in any order, except for one important exception: any xsl:import elements, if present, must come first, before all other top-level elements.

Instructions

An instruction is any XSLT element that can occur in the context of a “template,” which is what the XSLT 1.0 spec calls code that creates part of the result tree (or, when inside xsl:variable, a result tree fragment that may or may not be copied into the final result tree). Instructions are usually interleaved with literal result elements and their attributes. Literal result elements are elements that are not in the XSLT namespace. Here are all the XSLT instructions, listed in alphabetical order:

xsl:apply-importsxsl:fallback
xsl:apply-templatesxsl:for-each
xsl:attributexsl:if
xsl:call-templatexsl:message
xsl:choosexsl:number
xsl:commentxsl:processing-instruction
xsl:copyxsl:text
xsl:copy-ofxsl:value-of
xsl:elementxsl:variable

Tip

Among the XSLT instructions, xsl:variable is unique in that it also may occur as a top-level element.

The most common “template” context is, naturally, the content of the xsl:template element, which means that any of the instructions may occur as children of xsl:template. There are many other “template” contexts—the content of literal result elements, some top-level elements, special elements, and many of the instructions themselves. For example, xsl:for-each can be nested inside itself because it also represents a “template” context. The comprehensive set of “template” contexts can be gleaned from the element reference later in this chapter, which describes the content model of each XSLT element.

Tip

In XSLT 2.0, a series of instructions is called a “sequence constructor” rather than “template.” This terminology is more consistent with 2.0’s sequence-oriented model, and it also avoids any confusion around the overloaded term “template.”

Special Elements

Here are all the elements that don’t fit into the other two categories; they represent “special” elements that have unique rules about where they may occur:

xsl:otherwisexsl:transform
xsl:paramxsl:when
xsl:sortxsl:with-param
xsl:stylesheet 

For the sake of completeness, here are the corresponding rules for where these elements may occur:

  • xsl:stylesheet and xsl:transform are interchangeable names for the document element of an XSLT stylesheet.

  • xsl:when and xsl:otherwise may only occur as children of the xsl:choose instruction; the optional xsl:otherwise element must come last.

  • xsl:sort elements may occur only as children of xsl:apply-templates or xsl:for-each; when inside xsl:for-each, they must come first.

  • xsl:with-param elements may occur only as children of xsl:apply-templates or xsl:call-template.

  • xsl:param elements may occur only as the first children of xsl:template.

Tip

Among the special elements, xsl:param is unique in that it may also occur as a top-level element.

QNames

The names of internal XSLT objects are specified as QNames. Chapter 2 explained that QName name tests in an XPath expression are expanded using the in-scope namespace declarations, with the exception that a default namespace declaration is not used (i.e., a namespace declaration with no prefix, declared by xmlns). Internal XSLT object names are expanded according to these same rules; i.e., default namespace declarations are not considered. To put one of these object names in a namespace, you would need to use a prefix. Here are the objects in XSLT whose names are specified as QNames:

Named templatesKeys
ModesDecimal formats
Attribute setsVariables and parameters

Element Reference

This section enumerates all the elements in the XSLT namespace that are a part of XSLT 1.0. The valid syntax of each element, including its attributes and content, is described using the notation provided in Appendix B of the XSLT Recommendation (http://www.w3.org/TR/xslt#element-syntax-summary).

Attribute names in bold type represent required attributes. All other attributes are optional.

The attribute value placeholder for each attribute describes the allowed format of its value, e.g., node-set-expression or qname. An attribute value placeholder that has curly braces ({ }) around it means that the attribute is interpreted as an attribute value template. See the section Attribute Value Templates in Chapter 3.

The content model of each element is described in a comment inside the element. An empty element means that the element must always be empty.

<xsl:apply-imports>

<xsl:apply-imports/>

The xsl:apply-imports instruction applies templates to the current node in the current template rule’s mode, taking into consideration only the template rules that were imported into the stylesheet containing the current template rule. It is illegal for xsl:apply-imports to occur as a descendant of xsl:for-each since the current template rule property is considered to be set to null when an xsl:for-each element is instantiated.

For example, a stylesheet called top.xsl contains the following elements:

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

<xsl:template match="footnote" mode="misc">
  <br/>
  <xsl:apply-imports/>
</xsl:template>

And a stylesheet that it imports, called imported.xsl, contains this template rule:

<xsl:template match="footnote" mode="misc">
  <b>
    <xsl:value-of select="."/>
  </b>
</xsl:template>

When templates are first applied to a footnote element in the misc mode, only the matching template rule in top.xsl is considered because it has higher import precedence than the matching template rule in imported.xsl. However, xsl:apply-imports instructs the XSLT processor to once again apply templates to the current node (footnote) in the same mode (misc), only this time ignoring the current template rule and considering only the template rules that were overridden. In this case, the net effect is that a br element is inserted before the result of the overridden template rule:

<br/>
<b>...</b>

In this way, a template rule can be overridden but also reused within the template rule that overrides it.

Tip

XSLT 2.0 introduces the xsl:next-match instruction, which provides even greater power for invoking overridden template rules. It considers not only imported template rules, but also template rules with lower priority than the current template rule.

<xsl:apply-templates>

<xsl:apply-templates
  select = node-set-expression
  mode = qname>
  <!-- Content: (xsl:sort | xsl:with-param)* -->
</xsl:apply-templates>

The xsl:apply-templates instruction applies templates to each of the nodes selected by the node-set expression in its select attribute. If the select attribute is absent, then it defaults to the expression node( ), which selects all child nodes of the current node.

The mode attribute restricts the considered template rules to those in the given mode, i.e., only those xsl:template elements that have a mode attribute with the same value as the mode attribute of the xsl:apply-templates instruction. When the mode attribute is absent, then only those template rules in the unnamed default mode are considered, i.e., only those xsl:template elements that do not have a mode attribute (but that do have a match attribute).

By default, xsl:apply-templates iterates over the supplied node-set in document order. The order can be changed by placing one or more xsl:sort elements inside the xsl:apply-templates instruction. See <xsl:sort> later in this chapter.

The xsl:apply-templates instruction may also contain one or more xsl:with-param elements for passing named parameters to the invoked template rules. See <xsl:with-param> later in this chapter.

This example’s use of the xsl:apply-templates instruction is quite common:

<xsl:apply-templates/>

It applies templates to all children of the current node, considering only the template rules in the unnamed default mode.

Here’s one more example that uses all the allowed syntax features of the instruction:

<xsl:apply-templates select="*" mode="chart">
  <xsl:sort select="@size" data-type="number"/>
  <xsl:with-param name="format" select="'alternate'"/>
</xsl:apply-templates>

It applies templates in the chart mode to the child elements (*) of the current node, sorting them by the numeric value of their size attributes and passing to each template rule a parameter named format that has the string value alternate.

<xsl:attribute>

<xsl:attribute
  name = { qname }
  namespace = { uri-reference }>
  <!-- Content: template -->
</xsl:attribute>

The xsl:attribute instruction adds an attribute to the containing result element, whether created by xsl:element or a literal result element. The expanded-name of the resulting attribute is determined by the required name attribute and an optional namespace attribute. The local part of the name attribute’s QName value (the name minus the optional prefix) is used as the local name of the resulting attribute.

How the namespace of the resulting attribute is determined depends on whether the namespace attribute is present. When present, its value is used as the namespace of the resulting attribute. When absent, the QName value of the name attribute is expanded using the in-scope namespace bindings for the xsl:attribute element (not including any default namespace declaration). The resulting expanded-name is used as the expanded-name of the newly created attribute.

Warning

Since it is an error to add an attribute to an element after children have been added to it, you must make sure that xsl:attribute comes before any child elements, text nodes, etc. Otherwise, the XSLT processor may recover silently from the error by ignoring the xsl:attribute instruction.

Here is an example use of the xsl:attribute instruction:

<xsl:attribute name="style">display:none;</xsl:attribute>

Since both the name and namespace attributes are interpreted as attribute value templates, this is also a valid example:

<xsl:attribute name="{@name}" namespace="{@uri}">
 foo</xsl:attribute>

<xsl:attribute-set>

<xsl:attribute-set
  name = qname
  use-attribute-sets = qnames>
  <!-- Content: xsl:attribute* -->
</xsl:attribute-set>

The xsl:attribute-set element is a top-level element that declares a named attribute set, which lets you use the same set of attributes in more than one place in a stylesheet. The required name attribute identifies the attribute set by expanding its QName value. The content of the xsl:attribute-set element consists of a sequence of xsl:attribute elements that make up the attributes in the set. The optional use-attribute-sets attribute enables an attribute set to be composed additionally of other named attribute sets in the stylesheet. Its value is a whitespace-separated list of attribute set names. The attributes from other attribute sets are treated as if they’re added, in the order the attribute sets are named, before all the attributes in the set that uses them. If there are duplicate attributes with the same expanded-name in the resulting set, then the last attribute declared replaces any duplicate attributes declared previously.

An attribute set is used either by adding the use-attribute-sets attribute to an xsl:element or xsl:copy instruction, or by adding the xsl:use-attribute-sets attribute to a literal result element. The effect in either case is that attributes in the set are added to the resulting element, just as if the xsl:attribute instructions had been physically copied to that location in the stylesheet. The name, namespace, and value of each attribute in the set are evaluated in the same context as the containing element, with one exception: the only variable bindings that are visible are those in the context of the xsl:attribute-set element itself, i.e., top-level variables and parameters.

Duplicate attributes with the same expanded-name are treated the same way as with duplicates resulting from an attribute set using another attribute set; i.e., the last one declared overrides an earlier duplicate. However, when a literal result element has literal attributes attached to it, those override any attributes with the same expanded-name that are added to the element using xsl:use-attribute-sets.

<xsl:call-template>

<xsl:call-template
  name = qname>
  <!-- Content: xsl:with-param* -->
</xsl:call-template>

The xsl:call-template instruction instantiates a particular xsl:template element identified by name. It is an error if there are no xsl:template elements with a name attribute having the given expanded-name. Parameter values may be passed to a template using one or more nested xsl:with-param elements. See <xsl:with-param>.

Unlike xsl:apply-templates, the xsl:call-template instruction does not change the current node and current node list. For example, consider xsl:call-template:

<xsl:template match="para">
  <xsl:call-template name="do-para"/>
</xsl:template>

It instantiates the do-para named template:

<xsl:template name="do-para">
  <xsl:value-of select="."/>
</xsl:template>

The xsl:value-of instruction inside this named template will output the value of the para element because it is still the current node, represented by the XPath expression ".“.

<xsl:choose>

<xsl:choose>
  <!-- Content: (xsl:when+, xsl:otherwise?) -->
</xsl:choose>

The xsl:choose instruction selects among one or more conditional branches of execution. It is XSLT’s version of an if-else statement. It must contain one or more xsl:when elements, followed by an optional xsl:otherwise element. Each xsl:when element has a test attribute containing an XPath expression that is interpreted as a boolean. The content of the first xsl:when element whose test expression returns true is instantiated, and the remaining branches are ignored. If none of the test expressions return true, then the content of the xsl:otherwise element, if present, is instantiated. If none are true and xsl:otherwise is absent, then nothing is created.

For example:

<xsl:choose>
  <xsl:when test="$format='normal'">
    ...
  </xsl:when>
  <xsl:when test="$format='alternate'">
    ...
  </xsl:when>
  <xsl:otherwise>
    ...
  </xsl:otherwise>
</xsl:choose>

In this case, which branch is instantiated depends on the value of the $format variable. If it is not equal to normal or alternate, then the content of xsl:otherwise is instantiated.

<xsl:comment>

<xsl:comment>
  <!-- Content: template -->
</xsl:comment>

The xsl:comment instruction creates a comment node in the result tree. The content of the xsl:comment element is a template for the string-value of the comment node. It is an error to create any kind of node other than a text node inside xsl:comment. Also, the comment text must not contain the string "—“.

For example:

<xsl:comment>This comment will appear in the result tree
    </xsl:comment>

This instruction will create this comment in the result:

<!--This comment will appear in the result tree
    -->

<xsl:copy>

<xsl:copy
  use-attribute-sets = qnames>
  <!-- Content: template -->
</xsl:copy>

The xsl:copy instruction makes a copy of the current node. It is most useful when the current node is an element node. Rather than creating a full copy of the element (as with xsl:copy-of), xsl:copy creates a “shallow” copy—an element with the same expanded-name, including the original element’s namespace nodes. However, the children and attributes of the original element are excluded. Instead, the template content of the xsl:copy element determines what attributes and children the copied element will have.

When the current node is a text node, comment, processing instruction, attribute, or namespace node, <xsl:copy/> acts the same as <xsl:copy-of select="."/>, and if xsl:copy contains any template content, it is ignored. When the current node is a root node, the opposite happens. Only the template content of xsl:copy is instantiated; since the result tree’s root node is created automatically, it does not need to be explicitly copied, so the xsl:copy start and end tags are effectively ignored.

The optional use-attribute-sets attribute is used when copying element nodes only. See <xsl:attribute-set> earlier in this chapter.

A common example use of the xsl:copy instruction is as a part of the identity transformation template rule, shown here:

<xsl:template match="@*|node(  )">
  <xsl:copy>
    <xsl:apply-templates select="@*|node(  )"/>
  </xsl:copy>
</xsl:template>

This template rule matches attributes and child nodes (elements, comments, processing instructions, and text nodes). It recursively copies element nodes by making a shallow copy of the element and then applying templates to all of its attributes and children. When the current node is not an element, it is simply copied to the result, and the xsl:apply-templates instruction is ignored.

<xsl:copy-of>

<xsl:copy-of
  select = expression/>

The xsl:copy-of instruction performs a deep copy of each of the nodes in the select expression node-set, in document order. A deep copy includes all of the node’s children, attributes, and namespace nodes. If the select expression is a variable reference whose value is a result tree fragment, then it is treated as if it were a node-set containing one root node, and the entire fragment is copied to the result.

If the select expression returns a value of a different data type (e.g., number or boolean), then the value is converted to a string and copied to the result. In such cases, xsl:copy-of behaves no differently than the xsl:value-of instruction.

<xsl:decimal-format>

<xsl:decimal-format
  name = qname
  decimal-separator = char
  grouping-separator = char
  infinity = string
  minus-sign = char
  NaN = string
  percent = char
  per-mille = char
  zero-digit = char
  digit = char
  pattern-separator = char />

The xsl:decimal-format element is a top-level element that declares a decimal format that configures the behavior of the format-number( ) function. The name attribute identifies the decimal format and is referenced by the third argument of the format-number( ) function. If the name attribute is absent, then the element defines the default decimal format for this transformation.

We can classify the rest of the attributes on the xsl:decimal-format element into three categories:

  • Those that specify characters that may appear in the result of formatting the number

  • Those that control the interpretation of characters in the format pattern

  • Those that do both of the above

The following attributes specify characters or strings that may appear in the resulting formatted number:

infinity

Specifies the string used to represent infinity. Default is Infinity.

NaN

Specifies the string used to represent NaN. Default is NaN.

minus-sign

Specifies the character used as the default minus sign. Default is the hyphen-minus character (#x2D).

The following attributes control the interpretation of characters in the format pattern:

digit

Specifies the character used for a digit in the format pattern. Default is the number sign (#).

pattern-separator

Specifies the character used to separate positive and negative sub-patterns in the format pattern. Default is the semicolon (;).

The following attributes both control the interpretation of characters in the format pattern and specify characters that may appear in the result of formatting the number:

decimal-separator

Specifies the character used for the decimal sign. Default is the period (.).

grouping-separator

Specifies the character used for grouping (e.g., thousands). Default is the comma (,).

percent

Specifies the character used as a percent sign. Default is the percent character (%).

per-mille

Specifies the character used as a per mille sign. Default is the Unicode per mille character (#x2030).

zero-digit

Specifies the character used as the digit zero. Default is the digit zero (0).

For example, given this decimal format declaration:

<xsl:decimal-format name="alternate"
  decimal-separator=","
  grouping-separator="."/>

and this format-number( ) invocation:

format-number(10000.123, '#.##0,00', 'alternate')

the following string will be returned: 10.000,12.

Here’s another example that uses the default decimal format and outputs a currency value:

format-number(5242.1, '$#,##0.00')

This example returns the following string:

$5,242.10

Tip

The XSLT 1.0 recommendation defers the particular rules for how the format pattern string is interpreted to the JDK 1.1 specification. To remove that dependency on an old Java spec, the XSLT 2.0 specification defines the particular (virtually unchanged) rules itself.

See also <xsl:number>, which has its own distinct number formatting functionality, later in this chapter.

<xsl:element>

<xsl:element
  name = { qname }
  namespace = { uri-reference }
  use-attribute-sets = qnames>
  <!-- Content: template -->
</xsl:element>

The xsl:element instruction creates an element node. The expanded-name of the resulting element is determined by the required name attribute and an optional namespace attribute. The local part of the name attribute’s QName value (the name minus the optional prefix) is used as the local name of the resulting element.

How the namespace of the resulting element is determined depends on whether the namespace attribute is present. When present, its value is used as the namespace of the resulting element. When absent, the QName value of the name attribute is expanded using the in-scope namespace bindings for the xsl:element element, including any default namespace declaration. The resulting expanded-name is used as the expanded-name of the newly created element.

The optional use-attribute-sets attribute causes one or more sets of attributes to be created on the resulting element. See <xsl:attribute-set>.

Here is an example use of the xsl:element instruction:

<xsl:element name="div">...</xsl:attribute>

This is equivalent to using a literal result element:

<div>...</div>

The xsl:element instruction is most useful when you need to compute the name of the element at runtime, which is not possible with a literal result element. It is possible with xsl:element because both the name and namespace attributes are interpreted as attribute value templates. For example, to effectively make a shallow copy of an element without copying any of its namespace nodes (which is what happens with xsl:copy), you can use the xsl:element instruction to create a new element node having the same name and namespace URI:

<xsl:element name="{name(  )}"
    namespace="{namespace-uri(  )}">...</xsl:element>

<xsl:fallback>

<xsl:fallback
  <!-- Content: template -->
</xsl:fallback>

The xsl:fallback instruction provides an alternate implementation of the parent instruction in the event that the parent instruction is not recognized by the XSLT processor. This is possible either because the XSLT instruction is from a future version of XSLT or because the element is an extension element for which the XSLT processor does not have an implementation.

The xsl:fallback element is instantiated only when the parent instruction element is not recognized.

For example, the following stylesheet is designed to be portable between XSLT 2.0 processors, XSLT 1.0 processors that support the EXSLT extensions, and Xalan. It provides three possible instructions for multiple output documents: XSLT 2.0’s xsl:result-document, EXSLT’s exsl:document, and Xalan’s redirect:write extension.

<xsl:stylesheet version="2.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:exsl="http://exslt.org/common"
  xmlns:redirect="http://xml.apache.org/xalan/redirect"
  extension-element-prefixes="exsl redirect">

  <xsl:template match="/">
    <xsl:result-document href="output.xml">
      <xsl:call-template name="do-document"/>
      <xsl:fallback>
        <exsl:document href="output.xml">
          <xsl:call-template name="do-document"/>
          <xsl:fallback>
            <redirect:write file="output.xml">
              <xsl:call-template name="do-document"/>
            </redirect:write>
          </xsl:fallback>
        </exsl:document>
      </xsl:fallback>
    </xsl:result-document>
  </xsl:template>

  <xsl:template name="do-document">
    <foo/>
  </xsl:template>

</xsl:stylesheet>

In the event that this is a 1.0 processor, it will not recognize the xsl:result-document instruction and will instantiate the nested xsl:fallback instruction instead. If it, in turn, does not implement the exsl:document extension, then it will try to instantiate the redirect:write extension element. If it does not recognize that element either, then it will finally throw an error because there is no fallback provided for that scenario.

You can also perform fallback processing with the element-available( ) function and conditional processing. See the element-available( ) function in Chapter 5.

<xsl:for-each>

<xsl:for-each
  select = node-set-expression>
  <!-- Content: (xsl:sort*, template) -->
</xsl:for-each>

The xsl:for-each instruction iterates over each of the nodes in the node-set returned by the expression in its select attribute. By default, it iterates over them in document order. One or more nested xsl:sort elements can change the ordering. See <xsl:sort>.

The template content of the xsl:for-each instruction is instantiated once for each node in the node-set. Like xsl:apply-templates, xsl:for-each changes the current node and current node list context. Each node in the node-set in turn becomes the current node, and the entire node-set becomes the current node list.

For example, this instruction iterates over the set of order child elements of the current node outside the xsl:for-each element.

<xsl:for-each select="order">
  <br/>
  The phone number for this order is <xsl:value-of select=
    "phone"/>.
</xsl:for-each>

Inside the xsl:for-each element, however, the current node changes. Each of the order elements being iterated over takes its turn as the current node, so that the phone expression inside the xsl:for-each element is evaluated with an order element as the current node. Effectively, it selects the phone child element of the current order element.

<xsl:if>

<xsl:if
  test = boolean-expression>
  <!-- Content: template -->
</xsl:if>

The xsl:if instruction instantiates its template content only if the XPath expression in its test attribute evaluates to true after converting it to a boolean.

For example, the following xsl:if instruction will output a comma to the result tree only if the current node is not the last node in the current node list:

<xsl:if test="position(  ) != last(  )">
  <xsl:text>,</xsl:text>
</xsl:if>

<xsl:import>

<xsl:import
  href = uri-reference/>

The xsl:import element is a top-level element that imports another stylesheet into the current stylesheet. It is unique among the top-level elements; if present, it must come before all other top-level elements. In other words, all xsl:import elements in a stylesheet must occur as the first children of the xsl:stylesheet or xsl:transform element.

The value of the href attribute is a URI reference to the stylesheet being imported. It is resolved relative to the base URI of the xsl:import element itself.

Unlike xsl:include, xsl:import enables one stylesheet to override definitions in another stylesheet. If there are any like-named global variables, named templates, or multiple matching template rules, then those with the highest import precedence are chosen. Import precedence for a given top-level element (e.g., xsl:template, xsl:variable, or xsl:param) is determined by where its stylesheet occurs in the import tree.

The top stylesheet invoked by the XSLT processor is considered to be the root of the import tree. Each of its xsl:import elements represents a child of the root in the import tree. Likewise, each of the xsl:import elements inside the imported stylesheets represents a child of the imported stylesheet in the import tree, and so on.

For example, given a stylesheet A.xsl that imports B.xsl, C.xsl, and D.xsl (in that order), and given that B.xsl imports E.xsl, and given that D.xsl imports F.xsl and G.xsl (in that order), the resulting import tree could be represented like the tree shown in Figure 4-1.

Visualization of an example import tree

Figure 4-1. Visualization of an example import tree

The resulting import precedence, from highest to lowest, is: A.xsl, D.xsl, G.xsl, F.xsl, C.xsl, B.xsl, E.xsl. This is technically a reverse post-order traversal of the import tree. Another way of thinking about it is that there are two ordering rules. In a given stylesheet:

  • All of the definitions in the current stylesheet have higher import precedence than any definitions imported by this stylesheet.

  • The definitions imported later have higher import precedence than the definitions imported earlier.

If you apply these ordering rules for each stylesheet, then it will be easy to determine the relative import precedence among them.

Tip

All xsl:include directives are processed before computing the import tree. All included stylesheets are collapsed into the same “node” in the import tree so that all their definitions have the same import precedence as the stylesheet in which they’re included.

<xsl:include>

<xsl:include
  href = uri-reference/>

The xsl:include element is a top-level element that includes another stylesheet into the current stylesheet. It may appear anywhere in the stylesheet as a child of the xsl:stylesheet or xsl:transform element. The included stylesheet is included at the point where the xsl:include element occurs. It behaves as if all top-level elements from the included stylesheet were copied into the including stylesheet at that point, except that any xsl:import elements in the included stylesheet are moved up to the top, after any existing xsl:import elements in the including stylesheet.

The value of the href attribute is a URI reference to the stylesheet being included. It is resolved relative to the base URI of the xsl:include element itself.

The xsl:include element performs inclusion at the XML tree level, which means that it makes no special provision for handling conflicts that result from the inclusion. As usual, it is an error to have duplicate global variables, duplicate named templates, and more than one matching template rule with the same priority—regardless of whether they physically occur in the same stylesheet or whether they resulted from another stylesheet being included. If you want to allow one stylesheet to override definitions in another stylesheet, use xsl:import instead.

<xsl:key>

<xsl:key
  name = qname
  match = pattern
  use = expression/>

The xsl:key element is a top-level element that is used to declare a named key index that maps a set of strings to a set of node-sets. Each xsl:key element defines a separate, independent set of mappings that is identified as a whole by the required name attribute. XSLT’s key( ) function is used to retrieve the resulting node-set, given a key name and a string or set of string-values derived from a given node-set. See the key( ) function in Chapter 5.

The xsl:key element has the effect of building an index when the XSLT transformation begins. All nodes in the source documents that match the pattern in the required match attribute are included in the index.

Tip

The source documents (plural) consist of the source tree and any additional documents accessed by way of the document( ) function.

Each node that matches the pattern is subsequently mapped to a string or set of strings. This mapping is determined by evaluating the expression in the required use attribute using the matching node as the context node. If the expression returns a node-set, then the string-value of each node in the node-set is included in the set of strings that is mapped to the node. Otherwise, the expression’s value is converted to a string and that one string is mapped to the node.

For example, consider this source document, which contains cross-references from order elements to part elements:

<partsAndOrders>
  <part sku="12345">...</part>
  <part sku="54321">...</part>
  <part sku="ABCDE">...</part>
  ...
  <order part="54321">...</order>
  <order part="ABCDE">...</order>
  ...
</partsAndOrders>

A stylesheet that processes this document could build a key index for efficiently following these references. The xsl:key declaration would look something like this:

<xsl:key name="part-by-sku" match="part" use="@sku"/>

Then, the key( ) function would be used to retrieve the part, given a particular value. For example, when the current node is an order element, the part attribute’s value would be used.

<xsl:value-of select="key('part-by-sku',@part)/name"/>

Tip

The xsl:key element and the corresponding key( ) function provide an efficient way to traverse intra-document references that don’t use actual XML ID types. See also the note about the key( ) function in the Function Reference section in Chapter 5.

<xsl:message>

<xsl:message
  terminate = "yes" | "no">
  <!-- Content: template -->
</xsl:message>

The xsl:message instruction provides a way for an XSLT stylesheet to send a message (such as a stylesheet-specific warning, error, or diagnostics message) to a target other than the result tree. Where the message gets sent is dependent on the XSLT processor, but it usually gets output to the command-line window, if applicable, or stderr on Unix-based systems. The content of the message is the XML fragment resulting from the template content inside the xsl:message element.

If the optional terminate attribute is set to yes, then the XSLT process is terminated when the instruction is instantiated (after the message has been sent). This is useful for so-called “fatal errors.” The terminate attribute’s default value is no.

For example, xsl:message can be used to help debug a stylesheet:

<xsl:message>
  <xsl:text>The content of the $nodes variable is:
     </xsl:text>
  <xsl:copy-of select="$nodes"/>
</xsl:message>

<xsl:namespace-alias>

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

The xsl:namespace-alias element is a top-level element that is useful for XSLT stylesheets that generate another XSLT stylesheet as the result. It provides a way to disambiguate between elements in the XSLT namespace that are actual instructions and elements in the XSLT namespace that are literal result elements meant to appear in the result. The required stylesheet-prefix and result-prefix attributes refer to declared namespaces in the stylesheet by their prefixes (or #default for the default namespace). The effect of the xsl:namespace-alias element is that all literal result elements in the stylesheet, that are in the namespace identified by the stylesheet-prefix attribute, will appear in the result tree in the namespace identified by the result-prefix attribute. The stylesheet-prefix namespace is thus a temporary namespace that serves as an alias for the result-prefix namespace.

Here is an example stylesheet that generates another stylesheet. Without xsl:namespace-alias, the stylesheet author would have to use xsl:element for all the result elements, so that they would not be mistaken for XSLT instructions.

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

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

  <xsl:template match="/">
    <out:stylesheet version="1.0">
      <out:template match="/">
        ...
      </out:template>
    </out:stylesheet>
  </xsl:template>

</xsl:stylesheet>

All elements in the xsl namespace are actual XSLT elements to be interpreted as such in the current process, whereas all elements in the out namespace are just literal result elements whose final namespace, after resolving the namespace alias, will be the XSLT namespace.

<xsl:number>

<xsl:number
  level = "single" | "multiple" | "any"
  count = pattern
  from = pattern
  value = number-expression
  format = { string }
  lang = { nmtoken }
  letter-value = { "alphabetic" | "traditional" }
  grouping-separator = { char }
  grouping-size = { number } />

The xsl:number instruction is used to insert a formatted number into the result tree. It performs two primary functions, both applying to positive integers:

  • Assigning the current node a sequence number based on its position in the source tree

  • Formatting the number

It is possible to use xsl:number purely for its formatting capabilities. You can do that by supplying the number value yourself as an expression in the value attribute. The expression value is converted to a number as if by a call to the number( ) function. It is then rounded to the nearest integer, and the result is converted to a string, according to the formatting configuration specified by xsl:number’s formatting attributes (format, lang, letter-value, grouping-separator, and grouping-size), which we’ll discuss shortly.

Tip

When xsl:number assigns a sequence number to the current node—i.e., when the value attribute is absent—the only context it consults is the current node. The current node list and context size (what position( ) returns) are irrelevant.

If the value attribute is absent, the number is determined based on the position of the current node in the source tree. The level, count, and from attributes configure how that number is assigned. (When the value attribute is present, the level, count, and from attributes are ignored.)

The count and from attributes both contain patterns as their values. See the Patterns section in Chapter 3. Generally speaking, the count pattern determines which nodes will be counted, and the from pattern determines where the counting will begin. Precisely how this works in each case depends on the value of the level attribute. In all cases, when the count attribute is absent, it defaults to a pattern that matches any node with the same node type as the current node, and, if the current node has a name (e.g., because it’s an element), with the same expanded-name as the current node.

There are three general use cases, represented by the three possible values of the level attribute, as shown in Table 4-1.

Table 4-1. Three general use cases for xsl:number

Value of the level attribute

Use case and behavior

single (default)

This is for numbering a sequence of nodes at the same level, such as the items in a list.

The sequence number in this case is the sum of 1 and the number of preceding siblings of a particular target node that match the count pattern. If the current node matches the count pattern, then it functions as the target node. Otherwise, the processor searches the ancestors of the current node for a node that matches the count pattern. The first node it finds that matches the count pattern is used as the target node. However, if the from attribute is specified, then the only ancestors that are searched are those that are descendants of the nearest ancestor that matches the from pattern. If no target node is found, then the result is empty.

Note: The from attribute is not normally useful when level="single" is specified.

multiple

This is for numbering hierarchical sections and subsections, such as sections in an outline—e.g., I.A.2.b.

The sequence number in this case is a composite of multiple numbers, each of which is the sum of 1 and the number of preceding siblings of a target node for a particular level that match the count pattern. The list of individual sequence numbers corresponds to the list of target nodes, in document order. To find the target nodes, the processor searches the ancestor-or-self axis for nodes that match the count pattern. Each node that matches the count pattern is included in the list. However, if the from attribute is specified, then the only ancestors that are searched are those that are descendants of the nearest ancestor that matches the from pattern. If no target nodes are found, then the result is empty.

any

This is for numbering a sequence of nodes that may appear at any level of the document hierarchy, such as footnotes or comments.

The sequence number in this case is the number of nodes in the document up to and including the current node that match the count pattern, excluding namespace and attribute nodes. (Technically, this set is the union of the members of the preceding and ancestor-or-self axes that match the count pattern.) However, if the from attribute is specified, then only nodes that come after the nearest node that matches the from pattern are considered.

As mentioned earlier, the format, lang, letter-value, grouping-separator, and grouping-size attributes configure how the sequence number (or list of sequence numbers when level="multiple") is converted to a string.

The format attribute is a string that consists of an alternating sequence of format tokens and separator tokens. Format tokens consist of alphanumeric characters; separator tokens consist of non-alphanumeric characters. Each format token specifies the string to be used to represent the number 1 for the sequence number that corresponds to its position in the format string. The nth format token in the format string formats the nth sequence number in the list of numbers to be formatted. (Thus, it’s useful to have more than one format token in the format string only when level="multiple".) If there are more numbers than format tokens, the last format token will be used to format the remaining numbers. When the format attribute is absent, it defaults to the value 1 (a single format token with no separator tokens).

Separator tokens (consisting of non-alphanumeric characters) may appear at the beginning or end of the format string; in that case, the constructed string will begin or end with the corresponding token. Separator tokens that appear between format tokens serve to separate the numbers within a list of sequence numbers (i.e., when level="multiple"). In particular, each number after the first will be separated from the preceding number by the separator token preceding the format token used to format that number. If the format string contains no separator tokens, a default separator of "." (a period) is used to separate the numbers in the constructed string.

Numbering sequences can be numeric or alphabetic, depending on the value of the format token. Table 4-2 shows some example format tokens and the sequences they generate.

Table 4-2. Example format tokens and the sequences they generate

Format token

Generated sequence

1

1 2 3 4 ... 10 11 12 ...

A

A B C ... Z AA BB CC ...

a

a b c ... z aa bb cc ...

i

i ii iii iv v vi vii viii ix x ...

I

I II III IV V VI VII VIII IX X ...

The lang attribute indicates which language’s alphabet should be used for alphabetic numbering. Its default value depends on the system environment.

The letter-value attribute is used to disambiguate between numbering sequences for languages in which two different numbering sequences use the same initial alphabetic character. A value of alphabetic indicates that the numbering should follow the alphabet. A value of traditional indicates that the other numbering sequence in that language should be used.

The grouping-separator and grouping-size attributes must occur together. If only one of the two is specified, it is ignored. The grouping-separator attribute specifies the character that should be used to separate groups (e.g., thousands) within the number, and grouping-size specifies the size of each group (normally three). For example, grouping-separator="," and grouping-size="3" would construct numbers in this format: 10,000,000.

Here is an example of the first use case, numbering the items in a list. Given a list of item elements such as this:

<item>apples</item>
<item>bananas</item>
<item>oranges</item>
<item>pears</item>

and a template rule like this:

<xsl:template match="item">
  <xsl:number format="1. "/>
  <xsl:apply-templates/>
</xsl:template>

the following result would be created:

  1. apples

  2. bananas

  3. oranges

  4. pears

Next is an example of the second use case, numbering hierarchical sections and subsections. Given a document that has this structure:

<doc>
  <sect1>
    <title>Dissertation on Fruit</title>
    <sect2>
      <title>Apples</title>
      <sect3>
        <title>Flavor</title>
        ...
      </sect3>
      <sect3>
        <title>Color</title>
        ...
      </sect3>
      <sect3>
        <title>Size</title>
        ...
      </sect3>
    </sect2>
    ...
  </sect1>
  ...
</doc>

and a template rule like this:

<xsl:template match="title">
  <xsl:number level="multiple"
              count="sect1 | sect2 | sect3"
              format="I.A.1 "/>
  <xsl:apply-templates/>
</xsl:template>

the following titles will be produced:

I Dissertation on Fruit
  I.A Apples
    I.A.1 Flavor
    I.A.2 Color
    I.A.3 Size
  I.B Bananas
    I.B.1 Flavor
    I.B.2 Color
    etc.

Finally, here is an example of the third use case: numbering a sequence of items that may appear at any level of the document hierarchy. Given a document that has note elements at different levels of the hierarchy, such as this:

<doc>
  <prologue>
    <note>Don't count me.</note>
  </prologue>
  <section>
    <note>This is a note.</note>
    <p>... <note>This is also a note.</note></p>
    <p>... <i><note>This is an emphasized note.</note></i>
    </p>
  </section>
  <note>This is the last note.</note>
</doc>

and a template rule like this:

<xsl:template match="section//note | doc/note">
  <xsl:number level="any" from="section[1]" format="1. "/>
  <xsl:apply-templates/>
</xsl:template>

then the following result will be produced:

Don't count me.


  1. This is a note.
  ... 2. This is also a note.
  ... 3. This is an emphasized note.

4. This is the last note.

<xsl:otherwise>

<xsl:otherwise>
  <!-- Content: template -->
</xsl:otherwise>

The xsl:otherwise element is a special element because it may occur occur as the optional last child of the xsl:choose instruction. See <xsl:choose>.

<xsl:output>

<xsl:output
  method = "xml" | "html" | "text" | qname-but-not-ncname
  version = nmtoken
  encoding = string
  omit-xml-declaration = "yes" | "no"
  standalone = "yes" | "no"
  doctype-public = string
  doctype-system = string
  cdata-section-elements = qnames
  indent = "yes" | "no"
  media-type = string />

The xsl:output element is a top-level element that provides hints as to how the result tree should be serialized. They are only hints because, depending on the processing context, the XSLT processor may ignore them, or it may hand off serialization to a different software component altogether.

The method attribute indicates what format the serialized result tree should be in. The built-in formats are xml, html, and text. The XSLT processor may also provide other output methods, provided that they are identified by a QName with a prefix. The output method affects various aspects of serialization, such as how markup characters are serialized. In text format, for example, markup characters (<, &, and >) are serialized as literal characters, rather than entity references. In xml format, the result tree is serialized as a well-formed XML document or “well-balanced” XML fragment. In html format, the result tree is serialized in such a way that the HTML result is rendered correctly by legacy browsers.

When the method attribute (or the entire xsl:output element) is absent, the XSLT processor dynamically chooses between xml and html as the default output method. If the name of the document element of the result tree is any spelling of “HTML” (e.g., html, HTML, htML), and if it is not in a namespace, the html output method is used. Otherwise, the xml output method is used.

Tip

XSLT 2.0 adds xhtml to the built-in list of output methods.

The rest of xsl:output’s attributes provide parameters for the output method that is in effect. Which parameters are applicable depends on the value of the method attribute. Table 4-3 shows the applicability and default value of each parameter, for each of the built-in output methods (xml, html, and text). A grayed-out field means that the parameter is not applicable to that output method.

Table 4-3. Default values of applicable output method parameters

Parameter name

method="xml”

method="html”

method="text”

media-type

text/xml

text/html

text/plain

encoding

UTF-8 or UTF-16

[system-dependent]

[system-dependent]

version

1.0

4.0

 

indent

no

yes

 

doctype-system

[none]

[none]

 

doctype-public

[none]

[none]

 

omit-xml-declaration

no

  

standalone

[none]

  

cdata-section-elements

[none]

  

The version attribute indicates the version of the output method. The encoding attribute indicates what character encoding the result should be in. The omit-xml-declaration attribute specifies whether an XML declaration should be output in the result; its value must be yes or no. The standalone attribute specifies the (yes or no) value of a standalone document declaration to include in the XML declaration. When absent, no standalone declaration is output. The doctype-public and doctype-system attributes indicate which public and system identifiers, respectively, should be used in the document type declaration. The cdata-section-elements attribute specifies a list of the names of elements whose text node children should be wrapped in CDATA sections in the result. The indent attribute indicates whether additional whitespace should be added to the result to increase the document’s readability; its value must be yes or no. The media-type attribute specifies the media type (MIME content type) of the result.

<xsl:param>

<xsl:param
  name = qname
  select = expression>
  <!-- Content: template -->
</xsl:param>

The xsl:param element is both a top-level element and a special element. As a top-level element, it represents a global stylesheet parameter; how its value is set is implementation- dependent. (A common technique for command-line processors is to use command-line arguments to set stylesheet parameter values.) In its special form, an xsl:param element must occur as the first child (along with any other xsl:param elements) of the xsl:template element. In that case, it specifies a template parameter whose scope is limited to the template in which it is declared. The required name attribute specifies the name of the parameter. An optional default value can be supplied using either the select attribute or the template content of the xsl:param element. If the select attribute is absent and the xsl:param element is empty, then the default value of the parameter is an empty string. The parameter is initialized to the default value only when no parameter is explicitly passed to the template or stylesheet.

The xsl:param element serves the same function as the xsl:variable element, except that its default value is optional and can be overridden by a parameter passed to the stylesheet or template. See <xsl:variable>.

<xsl:preserve-space>

<xsl:preserve-space
  elements = tokens />

The xsl:preserve-space element is a top-level element that specifies a list of names of elements whose whitespace-only text node children should not be stripped from the source document prior to the transformation. Its use is only necessary when xsl:strip-space is also used in the same stylesheet because the default behavior is to not strip any text nodes from the source document. Its purpose is to provide a list of exceptions to the list specified by xsl:strip-space. For a fuller explanation of this process, see <xsl:strip-space>.

<xsl:processing-instruction>

<xsl:processing-instruction
  name = { ncname }>
  <!-- Content: template -->
</xsl:processing-instruction>

The xsl:processing-instruction instruction is used to insert a processing instruction (PI) node into the result tree. Its required name attribute specifies the PI target. Its content is a template for the string-value of the processing instruction. The resulting value must not include the string "?>“.

For example, the following instruction creates an XML stylesheet PI in the result:

<xsl:processing-instruction name="xml-stylesheet">
  <xsl:text>type="text/xsl" href="style.xsl"</xsl:text>
</xsl:processing-instruction>

The resulting PI looks like this:

<?xml-stylesheet type="text/xsl" href="style.xsl"?>

<xsl:sort>

<xsl:sort
  select = string-expression
  lang = { nmtoken }
  data-type = { "text" | "number" | qname-but-not-ncname }
  order = { "ascending" | "descending" }
  case-order = { "upper-first" | "lower-first" } />

The xsl:sort element is a special element that may occur only as a child of xsl:apply-templates or as the first child (along with any other xsl:sort elements) of xsl:for-each. It causes these instructions to process the relevant node-set in a different order than the default order, which is document order. Each xsl:sort element that is present specifies a sort key. The first xsl:sort element specifies the primary sort key, the second specifies the secondary sort key, etc.

The select attribute contains an expression that is evaluated for each node in the node-set, using that node as the current node and the entire node-set in document order as the current node list. The result is converted to a string, and that string is used as the sort key for that node. The select attribute’s default value is the expression ".“, which effectively causes the string-value of the node itself to be used as the sort key.

The rest of xsl:sort’s attributes configure how the sort keys are sorted. Each of these is interpreted as an attribute value template (AVT), evaluated relative to the current node outside the containing xsl:for-each or xsl:apply-templates instruction. Table 4-4 shows the four parameters, their allowed values, and their default values.

Table 4-4. Sort key configuration parameters

Parameter name

Allowed values

Default value

order

ascending
descending

ascending

lang

en, en-US, fr, etc.

[system-dependent]

data-type

text

number

[any QName with prefix]

text

case-order

upper-first
lower-first

[language-dependent]

The order attribute specifies whether the sort keys should be sorted in ascending or descending order. The lang attribute specifies the language of the sort keys. The system environment determines its default value.

The data-type attribute specifies the data type of the sort keys. A value of text causes the strings to be sorted lexicographically (e.g., in alphabetical order) as appropriate for the language (e.g., English). A value of number causes the sort keys to be converted to numbers and sorted numerically. Other implementation-defined data types can be referenced using a namespace-qualified QName. Finally, the case-order attribute specifies whether upper- or lowercase characters should be sorted first (when data-type="text").

The following example sorts the product elements alphabetically by the value of their title children:

<xsl:for-each select="product">
  <xsl:sort select="title"/>
  ...
</xsl:for-each>

<xsl:strip-space>

<xsl:strip-space
  elements = tokens />

The xsl:strip-space element is a top-level element that specifies which elements in the source tree should have their whitespace-only text node children stripped from them before beginning the transformation. The value of the required elements attribute is a list of patterns, each of which must conform to the XPath 1.0 NameTest production:

[37] NameTest       '*'
                    | NCName ':' '*'
                    | Qname

Tip

This is excerpted from the full XPath 1.0 grammar, which is included in Appendix A.

In other words, the list must only contain patterns such as *, xyz:*, foo, xyz:foo.

Whitespace stripping is an optional pre-process that can be applied to the source tree. Whitespace-only text nodes are text nodes whose string-value consists of space, tab, carriage return, or line feed characters only (#x20, #x9, #xD, or #xA). A text node that has at least one non-whitespace character is never stripped. By default, no text nodes are stripped from the source tree. However, if the xsl:strip-space element is present, all elements in the source tree that match one of the patterns in the elements attribute have all of their whitespace-only text node children stripped from them before the transformation begins.

There are two exceptions to this rule. If an individual element in the source tree has an ancestor element with xml:space="preserve" and no closer element has xml:space="default", then that element’s whitespace-only text node children are preserved, regardless of whether the element matches a pattern in the elements list. The other exception is when the element matches one of the patterns in the xsl:preserve-space element’s list of elements to preserve. The xsl:preserve-space element also has a required elements attribute that contains a list of patterns matching the XPath NameTest production. Its purpose is to specify exceptions to xsl:strip-space’s list of elements from which to strip whitespace. See also <xsl:preserve-space>.

Conflicts between matches in xsl:strip-space and xsl:preserve-space are resolved in the same way as conflicts between template rules. First, any match with lower import precedence than another is ignored. For example, if the same node matches two patterns (in xsl:strip-space or xsl:preserve-space’s elements list), one in an importing stylesheet and one in an imported stylesheet, then the pattern in the imported stylesheet is ignored. Second, any matching patterns that have a lower default priority than the default priority of another match are ignored.

The following example shows a typical use of the xsl:strip-space and xsl:preserve-space elements:

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

  <xsl:strip-space elements="*"/>
  <xsl:preserve-space elements="pre"/>

  ...

</xsl:stylesheet>

In this example, all elements in the source tree except for pre elements have their whitespace-only text node children stripped from them. (The pre pattern overrides the * pattern because it has higher priority.)

<xsl:stylesheet>

<xsl:stylesheet
  id = id
  extension-element-prefixes = tokens
  exclude-result-prefixes = tokens
  version = number>
  <!-- Content: (xsl:import*, top-level-elements) -->
</xsl:stylesheet>

The xsl:stylesheet element is the root, or document, element of the stylesheet. It is interchangeable with xsl:transform. The version attribute is required and indicates the version of XSLT being used, e.g., 1.0. The id attribute is only useful when the entire XSLT stylesheet is embedded inside another XML document.

The extension-element-prefixes and exclude-result-prefixes attributes both contain a list of namespace prefix tokens corresponding to namespaces that are declared in the stylesheet.

It is easy to end up with undesired namespace declarations in the result tree. That’s because, by default, a literal result element in the stylesheet automatically creates an element copy in the result tree that includes copies of all of its namespace nodes. Use the exclude-result-prefixes attribute to list all the namespaces that should not be included in the result tree at the end of the transformation.

The extension-element-prefixes attribute indicates which namespaces are namespaces of extension elements used in the stylesheet so that the XSLT processor will know to treat elements in one of these namespaces as an extension element. In addition, the namespaces listed in the extension-element-prefixes attribute are included in the list of namespaces to exclude from being copied to the result tree. See also the Extension Elements section in Chapter 6.

The allowed child elements of the xsl:stylesheet element are listed in the Top-Level Elements section earlier in this chapter.

<xsl:template>

<xsl:template
  match = pattern
  name = qname
  priority = number
  mode = qname>
  <!-- Content: (xsl:param*, template) -->
</xsl:template>

The xsl:template element is a top-level element that is used to define named templates and/or template rules. A named template is an xsl:template element that has a name attribute. It is invoked via the xsl:call-template instruction. A template rule is an xsl:template element that has a match attribute. It is invoked explicitly via the xsl:apply-templates instruction and implicitly by XSLT’s built-in template rules. A single xsl:template element functions both as a named template and as a template rule, if both the name and match attributes are present. All xsl:template elements must at least have either a name attribute or a match attribute.

The value of the match attribute is an XSLT pattern. It is an error if the pattern contains a variable reference. See the Patterns section in Chapter 3.

The optional mode and priority attributes are only allowed on template rules, i.e., when the match attribute is also present. The mode attribute indicates what mode this template rule is in. Modes are a way of segmenting template rules into different scopes. They are useful when you need to apply different template rules to the same node. A template rule in a given mode can be invoked only by an xsl:apply-templates instruction whose mode attribute has the same value, or by a built-in template rule in the same mode. When the mode attribute is absent, the template rule is in the single unnamed mode and can be invoked only by an xsl:apply-templates instruction that does not have a mode attribute, or by a built-in template rule in the unnamed mode.

The optional priority attribute allows you to override the default priority for a particular template rule. (The default priority is determined by the syntax of the pattern in the match attribute; see the Priority section in Chapter 3.)

Named templates and template rules can have named parameters, which are declared using one or more xsl:param elements that must occur as the first children of the element. Parameters are initialized by the xsl:call-template or xsl:apply-templates instruction used to instantiate the template. See <xsl:param>.

For a complete discussion of the XSLT processing model, including what the built-in template rules are, how templates rules are selected, and how template rule priority is determined, see the Processing Model section in Chapter 3.

<xsl:text>

<xsl:text
  disable-output-escaping = "yes" | "no">
  <!-- Content: #PCDATA -->
</xsl:text>

The xsl:text instruction is used to insert a text node into the result tree. While text nodes can also be inserted in any template context without using an xsl:text element, it can be useful for maintaining consistent code formatting (indentation) in an XSLT stylesheet, while being able to precisely control what whitespace should appear in the result tree. It’s also useful if you want to insert a whitespace-only text node into the result tree. That’s because XSLT processors strip all whitespace-only text nodes from your stylesheet when it builds the stylesheet tree—except for those inside the xsl:text element (or declared with xml:space="preserve").

For example, the following template rule does not use an xsl:text element. It outputs exactly one text node whose value is <name> is my name.

<xsl:template name="my-name">
  <xsl:value-of select="name"/> is my name.</xsl:template>

To achieve the same effect while still being able to maintain consistent element indentation, you can use the xsl:text element like so:

<xsl:template name="my-name">
  <xsl:value-of select="name"/>
  <xsl:text> is my name.</xsl:text>
</xsl:template>

For an explanation of the disable-output-escaping attribute, see Disabling Output Escaping in Chapter 3.

<xsl:transform>

<xsl:transform
  id = id
  extension-element-prefixes = tokens
  exclude-result-prefixes = tokens
  version = number>
  <!-- Content: (xsl:import*, top-level-elements) -->
</xsl:stylesheet>

The xsl:transform element is interchangeable with xsl:stylesheet as the root, or document, element of an XSLT stylesheet. It behaves exactly the same as xsl:stylesheet. Which element name you use is a matter of personal preference. See <xsl:stylesheet>.

<xsl:value-of>

<xsl:value-of
  select = string-expression
disable-output-escaping = "yes" | "no" />

The xsl:value-of instruction creates a text node in the result tree. The required select attribute is evaluated, the result is converted to a string, and the resulting string is used as the string-value of the text node.

Tip

When the select expression returns a node-set containing more than one node, the string-value of only the first node of the node-set in document order is used, and the rest are ignored. This is according to the rule for converting a node-set to a string, described in the Data Type Conversions section in Chapter 5.

For an explanation of the disable-output-escaping attribute, see the Disabling Output Escaping section in Chapter 3.

Here is an example use of the xsl:value-of instruction:

<xsl:value-of select="/page/title"/>

This creates a text node in the result tree whose string-value is the string-value of the title element in the source tree. If there is more than one title element, only the first title element in document order is used.

<xsl:variable>

<xsl:variable
  name = qname
  select = expression>
  <!-- Content: template -->
</xsl:variable>

The xsl:variable element is both an instruction and a top-level element. As a top-level element, it represents a global variable. As an instruction, it represents a local variable whose scope is limited to the element in which it is defined. The required name attribute specifies the name of the variable. The variable’s value is specified using either the select attribute or the template content. See also <xsl:param>.

If the select attribute is present, then the element must be empty. If the select attribute is absent and the xsl:variable element has non-empty content, then the value of the variable is a result tree fragment whose content is specified using the template content of the xsl:variable element. If the select attribute is absent and the xsl:variable element is empty, then the value of the variable is an empty string. See the Result Tree Fragments section in Chapter 2.

<xsl:when>

<xsl:when
  test = boolean-expression>
<!-- Content: template -->
</xsl:when>

The xsl:when element is a special element that may only occur as a child of xsl:choose. See <xsl:choose>.

<xsl:with-param>

<xsl:with-param
  name = qname
  select = expression>
  <!-- Content: template -->
</xsl:with-param>

The xsl:with-param element is a special element that must occur as a child of xsl:apply-templates or xsl:call-template. It passes a named parameter to the template rule or named template that is invoked. The value is specified the same way as with xsl:variable and xsl:param; i.e., you can use either the select attribute or the template content (which passes a result tree fragment) to specify the value of the parameter. If the select attribute is absent and the xsl:with-param element is empty, then the value passed is an empty string. If you pass a parameter to a template in which the parameter is not declared, it is simply ignored.

Here is an example of a parameter being passed to a named template:

<xsl:call-template name="show-price">
  <xsl:with-param name="price" select="35"/>
</xsl:call-template>

And here is a corresponding named template:

<xsl:template name="show-price">
  <xsl:param name="price"/>
  ...
</xsl:template>

See also <xsl:apply-templates> and <xsl:call-template>.

Get XSLT 1.0 Pocket Reference now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.