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

Subject: RE: [xsl] my node position within a certain context, efficiently?
From: "Michael Kay" <mike@xxxxxxxxxxxx>
Date: Sat, 25 Oct 2008 09:31:10 +0100
I would use

<xsl:template match="box//thing">
  <thing>
    <xsl:attribute name="myCount">
      <xsl:number from="box"/>
    </xsl:attribute>
    <xsl:apply-templates/>
  </thing>
</xsl:template>

Michael Kay
http://www.saxonica.com/ 

> -----Original Message-----
> From: Syd Bauman [mailto:Syd_Bauman@xxxxxxxxx] 
> Sent: 25 October 2008 05:14
> To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
> Subject: [xsl] my node position within a certain context, efficiently?
> 
> 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