Re: [xsl] The identity transform and attributes

Subject: Re: [xsl] The identity transform and attributes
From: Abel Braaksma <abel.online@xxxxxxxxx>
Date: Mon, 21 Jan 2008 12:06:22 +0100
Or this way of writing, which however makes overriding attribute through templates not an option:

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


But if speed is the discussion point here, I think that optimalisation is rather good. Meaning that your two versions (and possibly mine) do not cost any extra clock cycles, because the internal representation is (just about) equal anyway. But that's a terrain I know little about, perhaps Michael Kay can shed some light on that?


Btw, it is never possible to override the text() of an attribute. An attribute does not have children. I.e., the following would be nice to prevent the shallow copy to copy both the attribute and the text and then treat the text "child" of the attribute separately (and override special cases), but that's not gonna work:

<xsl:template match="@*">
    <xsl:attribute name="{name()}">
         <xsl:apply-templates select="text()" />
     </xsl:attribute>
</xsl:template>

<xsl:template match="@specialcase/text()">
    <xsl:text>other text</xsl:text>
</xsl:template>


I believe that on most processors the above will give you a compile time warning about child axis of attributes not selecting anything.


About your question whether "apply-templates has any effect on an attribute" I believe the answer is a definite no. And I am under the impression (but I cannot confirm from tests) that once an attribute is matched, any apply-templates to children of it are optimized away, as they have no effect anyway.

Cheers,

-- Abel Braaksma

Andrew Welch wrote:
I'm wondering if the default identity transform should be this:

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

Or this:

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

<xsl:template match="@*">
    <xsl:copy/>
</xsl:template>

The former is nice and compact, but when the node is an attribute node
does the apply-templates call have any effect - even if it's a few
clock cycles wasted?  It's a pointless instruction at that point.  I
guess it is too for non-element node()'s such as whitespace?

Also, the shallow copy copies the entire attribute, so there is no
opportunity to override the text() of the attribute.  The only way is
to add a separate matching template for the attribute - the latter
perhaps makes this a little clearer.

A useful distinction or a waste of time? :)

cheers

Current Thread