[xsl] my node position within a certain context, efficiently?

Subject: [xsl] my node position within a certain context, efficiently?
From: Syd Bauman <Syd_Bauman@xxxxxxxxx>
Date: Sat, 25 Oct 2008 00:13:48 -0400
I sorta suspect that if I knew what to look for, I could find this in
the archives or Dave Pawson's FAQ, but I haven't so far.

My input documents will look something like this:

  <stuff>
    <thing>zero</thing>
    <box>
      <thing>one</thing>
      <thing>two</thing>
      <list>
        <item>
          <thing>three</thing>
        </item>
        <item>
          <thing>four</thing>
        </item>
      </list>
      <note>
        <thing>five</thing>
        <thing>six</thing>
      </note>
      <thing>seven</thing>
      <thing>eight</thing>
    </box>
    <thing>nine</thing>
    <thing>ten</thing>
  </stuff>

That is, there are <thing>s both inside and outside of <box>es, and
those that are inside a <box> may be children or descendants at
almost any depth.

For each <thing> that is inside a <box> I want its position within
the box. I.e., for the above input, I'd like to be able to generate
the following output from within a template that has matched <thing>s
inside <box>es.

  <thing myCount="1">one</thing>
  <thing myCount="2">two</thing>
  <thing myCount="3">three</thing>
  <thing myCount="4">four</thing>
  <thing myCount="5">five</thing>
  <thing myCount="6">six</thing>
  <thing myCount="7">seven</thing>
  <thing myCount="8">eight</thing>

I pretty quickly came up with a way to do this. It would even work in
XSLT 1.0, although this particular stylesheet is in 2.0. But I am
wondering if there isn't a better way. Does this work for all such
cases, or have I missed something? Is this insanely inefficient?

  <xsl:template match="box//thing">
    <xsl:copy>
      <xsl:attribute name="myCount">
        <xsl:value-of select="1 + count(preceding::thing) - count(ancestor::box/preceding::thing)"/>
      </xsl:attribute>
      <xsl:apply-templates/>
    </xsl:copy>
  </xsl:template>

Thanks.

Current Thread