user3813234
user3813234

Reputation: 1682

Understanding xsl:copy with xsl:apply-templates (XSLT 2.0)

What is the difference between the following three templates?

<xsl:template match="food">
<xsl:copy>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>

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

<xsl:template match="food">
<xsl:copy>
</xsl:copy>
<xsl:apply-templates/>
</xsl:template>

My guess would be that the first and the second are the same. But what about the third one?

Upvotes: 1

Views: 2290

Answers (2)

Ian Roberts
Ian Roberts

Reputation: 122364

<xsl:template match="food">
<xsl:copy>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>

copies a food element, then applies templates to that element's child nodes (child elements, comments and text nodes), placing the results inside the copied element. It does not do anything to any attributes that the original food element had.

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

As above, but applies templates to the food element's attributes as well as its children. Whether this has any observable effect depends whether there are any templates that match these attribute nodes and what those templates do. If you have a general identity template (see below) then the copied food element would end up with the same attributes as the original one.

<xsl:template match="food">
<xsl:copy>
</xsl:copy>
<xsl:apply-templates/>
</xsl:template>

as in the first case, but places the result of applying templates to the children after the (empty) copied food element rather than inside it.

Generally you would expect to see templates of this kind alongside a general "identity" template

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

that copies everything unchanged except where more specific templates override this behaviour

Upvotes: 4

michael.hor257k
michael.hor257k

Reputation: 116959

My guess would be that the first and the second are the same.

No they are not the same. The first one does not apply templates to attributes. These two are the same:

<xsl:apply-templates>

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

But what about the third one?

The third one applies templates outside of the copied node, resulting in flattening the hierarchy: children will become siblings.

Upvotes: 1

Related Questions