Increment a value in XSLT

后端 未结 4 942
深忆病人
深忆病人 2020-12-09 02:36

I\'m reasonably new to xlst and am confused as to whether there is any way to store a value and change it later, for example incrementing a variable in a loop.

I\'m

相关标签:
4条回答
  • 2020-12-09 03:03

    I ran into that myself two years ago. You need to do use recursion for this. I forget the exact syntax, but this site might help:

    Tip: Loop with recursion in XSLT

    The strategy works basically as follows: Replace for loop with a template "method". Have it recieve a parameter i. Do the body of the for loop in the template method. If i > 0 call the template method again (recursion) with i - 1 as parameter.

    Pseudocode:

    for i = 0 to 10:
       print i
    

    becomes:

    def printer(i):
       print i
       if i < 10:
          printer(i + 1)
    printer(0)
    

    Please note that using position() in a xsl:for-each (see other answers) can be simpler if all you want to do is have a variable increment. Use the kind of recursion explained here if you want a more complicated loop / condition.

    0 讨论(0)
  • 2020-12-09 03:12

    XSLT is a functional language and among other things this means that variables in XSLT are immutable and once they have been defined their value cannot be changed.

    Here is how the same effect can be achieved in XSLT:

    <xsl:stylesheet version="1.0"
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
     <xsl:output omit-xml-declaration="yes" indent="yes"/>
     <xsl:strip-space elements="*"/>
    
     <xsl:template match="/">
       <posts>
        <xsl:for-each select="data/posts/entry">
            <xsl:variable name="i" select="position()" />
            <xsl:copy>
             <xsl:value-of select="concat('$i = ', $i)"/>
            </xsl:copy>
        </xsl:for-each>
       </posts>
     </xsl:template>
    </xsl:stylesheet>
    

    when this transformation is applied on the following XML document:

    <data>
     <posts>
      <entry/>
      <entry/>
      <entry/>
      <entry/>
      <entry/>
     </posts>
    </data>
    

    the result is:

    <posts>
        <entry>$i = 1</entry>
        <entry>$i = 2</entry>
        <entry>$i = 3</entry>
        <entry>$i = 4</entry>
        <entry>$i = 5</entry>
    </posts>
    
    0 讨论(0)
  • 2020-12-09 03:14

    Another approach (IE specific) we can follow is to take help of Javascript using "msxsl:script"

    <msxsl:script implements-prefix='yourprefix' language='JavaScript'>  
       <![CDATA[var counter=1; function getCounter(){return counter++;}]]>
    </msxsl:script>  
    

    Then we can call this method in our xsl

    <xsl:value-of select="yourprefix:getCounter()" />
    
    0 讨论(0)
  • 2020-12-09 03:18

    You can use the position() function:

    • Example 1
    • Example 2
    <xsl:for-each select="data/posts/entry">
      <xsl:text>
        Postion: '
      </xsl:text>
      <xsl:value-of select = "position()" />
      <xsl:text>
        '
      </xsl:text>
      <!-- DO SOMETHING -->
    </xsl:for-each>
    0 讨论(0)
提交回复
热议问题