xsl-list
[Top] [All Lists]

Re: [xsl] The identity transform and attributes

2008-01-21 08:57:39
Jesper Tverskov wrote:
This thread has been interesting to follow but why propose this:

<xsl:template match="element()">
  <xsl:copy>
      <xsl:apply-templates select="@*,node()"/>
  </xsl:copy>
</xsl:template>
<xsl:template match="attribute()|text()|comment()|processing-instruction()">
  <xsl:copy/>
</xsl:template>

When the old way is much shorter:

Shorter does not mean clearer.

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

The old way even has the power and fascination of being just one
template, the identity template.

I completely agree, but is power and fascination helpful to new students?

This is how the identity template
looks in two specs, in hundreds of books, in thousands of articles and
tutorials, and in millions of XSLT stylesheets until this very day.

Not really. The identity template looks different in most books, which makes it so hard to understand the subtleties involved (I never counted > 100 XSLT books, but I may be wrong, hopefully I am ;)

Why change things for the worse just to confuse people?

I am not under the impression that people on this list are giving suggestions "for the worse". Many people (sometimes including myself, but I deviate often), think that using attribute::foo, attribute() or attribute(foo) is more clear than using @foo, especially to first timers. When I started out I didn't have the faintest idea on what exactly the identity copy template meant (if you look hard you can find some beginners question from me in the archives asking about how @*|* differs from @* | node()).

That said, there's also a constant lobby for the other alternative, using a xsl:copy-of for everything we are not likely to have overrides for. But in terms of maintainability that's considered a poorer choice:

<xsl:template match="*">
   <xsl:copy>
<xsl:copy-of select="attribute()|comment()|processing-instruction()" />
      <xsl:apply-templates select="*" />
   </xsl:copy>
</xsl:template>

also, as I'm sure many are aware, this is not exactly an identity template anymore. Expanding it to the following is what I've seen often on the Net, but less frequent on this list:

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

which is a true identity template and, in my opinion, easier to understand than the concise one. Still, once people understand more what they're doing, I ask them to go to the easiest (read: shortest) template to write, but, arguably, the hardest to understand:

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

sometimes, depending on what you're after, changing node() to *, (but then, again, it is not a true identity template anymore).

What's however still beyond me (and maybe I missed it on this afternoon's very interesting thread) is why @* uses the combined syntax of * (element) and @ (attribute), while at the same time calling an attribute node a node, while at the same time using equally like syntax in other respects (attribute(), elements() etc), but not treating them equally (i.e., node() is supposed to be "any" node imo, but this is arguably not true as it does not include attribute nodes), putting them in a special position and making the identity template harder than it needed to be, i.e., I believe that from the start this should've been proficient back in 1997:

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

which would've been way easier to understand (and possibly easier to implement too).

Cheers,
-- Abel Braaksma

--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--