[XSL-LIST Mailing List Archive Home] [By Thread] [By Date]

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


Subject: Re: [xsl] my node position within a certain context, efficiently?
From: "Mukul Gandhi" <gandhi.mukul@xxxxxxxxx>
Date: Sat, 25 Oct 2008 11:24:04 +0530

It seems, a simple position() function would work here,

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                       version="2.0">

  <xsl:output method="xml" indent="yes" />

  <xsl:template match="/">
    <result>
      <xsl:apply-templates select="//box" />
    </result>
  </xsl:template>

  <xsl:template match="box">
    <box>
      <xsl:apply-templates select=".//thing" />
    </box>
  </xsl:template>

  <xsl:template match="thing">
    <thing myCount="{position()}"><xsl:value-of select="." /></thing>
  </xsl:template>

</xsl:stylesheet>

On Sat, Oct 25, 2008 at 9:43 AM, Syd Bauman <Syd_Bauman@xxxxxxxxx> wrote:
> 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.


-- 
Regards,
Mukul Gandhi


Current Thread
Keywords