14

The identity template looks like this:

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

Does <xsl:apply-templates select="@*|node()" /> select more than <xsl:apply-templates />, or could the identity template have been like this?

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

What exactly is selected when I do the following?

<xsl:apply-templates />
Svish
  • 152,914
  • 173
  • 462
  • 620

3 Answers3

20

Does <xsl:apply-templates select="@*|node()" /> select more than <xsl:apply-templates />, or could the identity template have been like this?

<xsl:apply-templates/> 

is equivalent to:

<xsl:apply-templates select="node()"/>

and this is a shorter former of:

<xsl:apply-templates select="child::node()"/>

and this is a equivalent to:

<xsl:apply-templates select="* | text() | comment() | processing-instruction()"/>

As we see from the last instruction, the xsl:apply-templates instruction you are asking about, doesn't select any attributes, therefore it cannot be used as a shorthand for:

<xsl:apply-templates select="@*|node()"/>
Dimitre Novatchev
  • 240,661
  • 26
  • 293
  • 431
  • @OP: P.S. this is defined at http://www.w3.org/TR/xslt#section-Applying-Template-Rules: "In the absence of a select attribute, the xsl:apply-templates instruction processes all of the children of the current node, including text nodes. ..." Note that attribute nodes are *not* considered children of their parent element. – LarsH Nov 20 '13 at 11:20
  • @LarsH, Yes, but sometimes readers find quoting the Specs to be "intimidating" :) – Dimitre Novatchev Nov 20 '13 at 14:25
  • Yeah, if I had to choose between only quoting the Spec and only explaining what it means, I would choose your answer (unless I thought the implications of the spec were very easy to understand on this point). However in conjunction with a helpful explanation, I think pointing users to the primary material helps them "learn how to fish." The OP here seems to be an accomplished programmer, who shouldn't be afraid of the spec. :-) – LarsH Nov 20 '13 at 15:44
5

The default select for <xsl:apply-templates/> is just "node()", it doesn't include attributes.

Ian Roberts
  • 120,891
  • 16
  • 170
  • 183
2

The default selection of apply-templates is node(), which is shorthand for child::node(). This XPath expressions is evaluated as follows:

  • First, all nodes from the "child" axis are taken. This are all the direct children of the current element, i.e. other elements, text, and comments, but not the attributes.
  • Then this node set is filtered with the node test "node()". In this case, no elements are filtered because that test matches everything.

So with <xsl:apply-templates />, templates for the child elements are applied but not for the attributes. In case of the copy template this would mean that the attributes are not copied.

oberlies
  • 11,503
  • 4
  • 63
  • 110