XSLT - find position() when inside a nested for-each

25,746

You should try modifying your input to:

<root>
  <element1>
    <child>
      <aaa>1a</aaa>
      <bbb>2a</bbb>
    </child>
  </element1>
  <element2/>
  <element3>3a</element3>
  <element3>3b</element3>
  <element3>3c</element3>
</root>

then see what you get with:

<xsl:template match="/">
    <test>
        <xsl:for-each select="root/element3">
        <xsl:variable name="parent-position" select="position()" />
        <xsl:variable name="parent-value" select="." />
            <xsl:for-each select="../element1/child/*">
                <item value="{.}" parent-value="{$parent-value}" parent-position="{$parent-position}" position="{position()}"/>
            </xsl:for-each>
        </xsl:for-each>    
    </test>
</xsl:template>
Share:
25,746
danw
Author by

danw

Updated on July 09, 2022

Comments

  • danw
    danw almost 2 years

    I'm using XSLT to perform a transformation on some fairly complex XML. In order to achieve the output I need to, I've had to create a nested for loop something like the following:

    Source XML

    <root>
      <element1>
        <child>
          <aaa></aaa>
          <bbb></bbb>
        </child>
      </element1>
      <element2/>
      <element3/>
      <element3/>
      <element3/>
    </root>
    

    XSLT

    <xsl:for-each select="element3">
      <!-- Do some stuff -->
    
      <xsl:for-each select="../element1/child/*">
        <!-- Do some more stuff -->
      </xsl:for-each>
    </xsl:for-each>
    

    Problem

    What I'm trying to do here is whilst in my nested loop (on ../element1/child/*) - I'd like to find out:

    1. The position of the element I'm currently looping - if, for example, I was currently focused on <bbb> then this position (I think) would be '1'
    2. The position of the parent loop (on element3) - so if, for example, I was on the third instance of <element3> and then looping through ../element1/child/* and was focused on <aaa> - the two values I would be after would be '2' and '0'.

    Ideally, I'd like to be able to assign these values to a variable. I've tried using the position() notation like below but this doesn't seem to be working.

    <xsl:for-each select="../element1/child/*">
      <xsl:variable name="postion_current_loop" select="position()"/>
      <xsl:variable name="postion_parent_loop" select="??????"/>
      <!-- Do some more stuff -->
    </xsl:for-each>
    

    If anyone has any ideas on how I could achieve this that would be greatly appreciated! I'm using XSLT 2.0, but am open to solutions using XSLT 1.0 if need be. Thanks in advance.