tags:

views:

19

answers:

2

Lets say you have an xml document like

<parents>
    <parent>
        <element />
        <element />
    </parent>
    <parent>
        <element />
        <element />
    </parent>
</parents>

While processing I need to know that the elements are 1, 2, 3, 4 in the document, not that but calling position() will return 1, 2, 1, 2. Normally I would modify the xml, but, in this case, it is not possible, while I am processing parent 2, I somehow need to know that it's first element, is really element 3.

Thanks, -c

+4  A: 

Use <xsl:number>

This transformation:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&gt;
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

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

 <xsl:template match="element">
     <xsl:copy>
       <xsl:number level="any" count="element"/>
     </xsl:copy>
 </xsl:template>
</xsl:stylesheet>

when applied on the provided XML document:

<parents>
    <parent>
        <element />
        <element />
    </parent>
    <parent>
        <element />
        <element />
    </parent>
</parents>

produces the wanted result:

<parents>
    <parent>
        <element>1</element>
        <element>2</element>
    </parent>
    <parent>
        <element>3</element>
        <element>4</element>
    </parent>
</parents>
Dimitre Novatchev
+1 Good answer.
Alejandro
+2  A: 

Got it, it's actually quite simple

<xsl:value-of select="count(preceding::element)"/>
Chad
This will not be correct if an `<element>` contains another `<element>`
Dimitre Novatchev
@Dimitre Novatchev, in my situation it won't, but I used your solution in my code anyhow.
Chad
@Chad: +1 Another approach. For nested `element` you could use: `count(preceding::element|ancestor::element)`. But, do note that for complex hierarchy restrictions (counting not from the whole tree but from some ancestor) the expression could become very complex. For that is xsl:number/@level and xsl:number/@from.
Alejandro