xslt-1.0

Why does the W3C XSLT 1.0 specification miss the info about "mode-specific" template rules for nodes other than root and element nodes?


Section 5.8 (Built-in Template Rules) of W3C specs for XSLT 1.0 explicitly lists built-in template rules and their behaviour for all node types in the "no-mode" case (<xsl:template> without mode attribute). Yet, for "mode-specific" case only a built-in template rule for root and element nodes, with this equivalent form:

<xsl:template match="*|/" mode="m">
  <xsl:apply-templates mode="m"/>
</xsl:template>

is defined. There's no mention of built-in "mode-specific" template rules for other nodes which kind of suggests those don't exist. Yet, a simple example proves that they do. The following source document/stylesheet pair:

<myelement attr="foo">TEXT</myelement>

and

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output omit-xml-declaration="yes"/>

  <xsl:template match="*|/">
    <xsl:apply-templates select="myelement/text()" mode="m"/>
    <xsl:apply-templates select="myelement/@*" mode="m"/>
  </xsl:template>

</xsl:stylesheet>

generates the following output:

TEXTfoo

which would not be the case if there were no auto-generated/implicit/built-in "mode-specific" template rules for text and attribute nodes. Is this a defect/omission in the specs, or am I, as an astute reader, reading the specs too literally, and the intention is simply that the implicit "mode-specific" template rules are there for all nodes and their default behaviour is exactly the same as for the "no-mode" case, even if not stated explicitly?

EDIT: To simplify my question even further: is the following template rule also implicitly defined in the "mode-specific" case?

<xsl:template match="text()|@*" mode="m">
  <xsl:apply-templates mode="m"/>
</xsl:template>

The specification is not entirely clear on this matter, it only mentions this one:

<xsl:template match="*|/" mode="m">
  <xsl:apply-templates mode="m"/>
</xsl:template>

Solution

  • I am afraid you are missing the true significance of the mode-specific built-in template rules.

    The specification states that:

    There is also a built-in template rule for each mode, which allows recursive processing to continue in the same mode in the absence of a successful pattern match by an explicit template rule in the stylesheet.

    What this means that even if an element was processed by a built-in template rule in mode m, its children will also be processed by a matching template in mode m - if such template is found.

    All that your example shows is that when there is no matching template (at all) for an attribute, the attribute will be processed by the built-in template rule. And since an attribute does not have child nodes, there is no need to "pass down" the mode for further processing. Likewise for a text node.