Incrementing and checking the counter variable in XSLT

后端 未结 6 1014
梦毁少年i
梦毁少年i 2020-11-29 09:56

I am having little difficulty in assigning a counter variable and incrementing it and then checking for a certain value in XSLT. Here is my code:



        
相关标签:
6条回答
  • 2020-11-29 10:09

    'Variables' in XSL are actually constants - you cannot change their value. This:

    <xsl:value-of select="$counter + 1"/> 
    

    will just output the value of $counter+1

    To do loops you have to use recursion - e.g.:

    <xsl:stylesheet 
      version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    
      <xsl:template name="loop">
        <xsl:param name="i"/>
        <xsl:param name="limit"/>
        <xsl:if test="$i &lt;= $limit">
          <div>
            <xsl:value-of select="$i"/>
          </div>
          <xsl:call-template name="loop">
            <xsl:with-param name="i" select="$i+1"/>
            <xsl:with-param name="limit" select="$limit"/>
          </xsl:call-template>
        </xsl:if>
      </xsl:template>
    
      <xsl:template match="/">
        <html>
          <body>
            <xsl:call-template name="loop">
              <xsl:with-param name="i" select="0"/>
              <xsl:with-param name="limit" select="10"/>
            </xsl:call-template>
          </body>
        </html>
      </xsl:template>
    
    </xsl:stylesheet>
    

    altough it is better to try to avoid loops - in most cases the XSL can be written to avoid it, but I don't understand enough of what are you trying to achieve to give you the complete solution.

    0 讨论(0)
  • 2020-11-29 10:12

    We cant update xsl:variable as they are just like constants. But we can updated dp:local-variables, so here dp:local-variable counter is initialized before starting for-loop. Each time loop is run counter will update itself by 1. Try This:

    <?xml version="1.0" encoding="utf-8"?>
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" <xsl:variable name="empty_string"/>
        <xsl:template match="/Collection">
            <dp:set-local-variable name="'counter'" value="0"/>
            <xsl:for-each select="Content">
                <dp:set-local-variable name="'counter'" value="dp:local-variable('counter')+1"/>
                <xsl:sort select="Html/root/Event/start_date" order="ascending"/>
                <xsl:variable name="isFutureEvent">
                    <xsl:value-of select="syscom:isFutureDate(Html/root/Event/start_date)" />
                </xsl:variable>
    
                <xsl:if test="Html/root/Event != $empty_string">
                    <xsl:if test="$isFutureEvent='true'">
    
                        <xsl:value-of select="dp:local-variable('counter')"/>
                        <!-- Test if Counter < 4 -->
                        <xsl:if test="dp:local-variable('counter') &lt; 3">
                            <div class="media">
                                <!-- Do stuff here -->
                            </div>
                        </xsl:if>
                        <!-- End if for counter -->  
                    </xsl:if>
                </xsl:if>
                <!--</xsl:when>-->
                <!--</xsl:choose>-->
            </xsl:for-each>
        </xsl:template>
    </xsl:stylesheet>
    
    0 讨论(0)
  • 2020-11-29 10:15

    I have same problem. I need increment value in loop. So the simplest way was include Saxon and use that value.

    if you use Saxon 6.5.5

    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    ...
    xmlns:saxon="http://icl.com/saxon"
    extension-element-prefixes="saxon"
    version="3.0">
    

    if you use Saxon 9.4.0.4

    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    ...
    xmlns:saxon="http://saxon.sf.net/"
    extension-element-prefixes="saxon"
    version="3.0">
    

    And after that you can simply use saxon variable :

    <xsl:variable name="counter" select="0" saxon:assignable="yes"/> <!-- declare value -->
    
    <saxon:assign name="counter" select="$counter+1"/> <!-- increment value, you can do it in loop for example-->
    
    <xsl:value-of select="$counter"></xsl:value-of> <!-- print value -->
    
    0 讨论(0)
  • 2020-11-29 10:19

    In case any one wants to do this while using .net (XslCompiledTransform) you can use

    <xsl:stylesheet ...  xmlns:customCode="urn:customCode">
    
    <msxsl:script language="VB" implements-prefix="customCode">
        <![CDATA[
        private mCounter As Integer
        Public Function AddToCounter() As Boolean
          mCounter += 1
          Return True
        End Function
        Public Function GetCounter() As Integer
          Return mCounter
        End Function
        ]]>
    </msxsl:script>
    

    Then you add a call to "customCode:AddToCounter()", and then you could write a message like this <xsl:message><xsl:value-of select="customCode:GetCounter()" /> rows remaining.</xsl:message>

    0 讨论(0)
  • 2020-11-29 10:21

    If you want to know where you are in a for-each loop, you can use the built-in position() function.

    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
        <xsl:template match="/Collection">
            <xsl:for-each select="Content">
                <xsl:if test="position() &lt; 3">
                    <!-- Do this for nodes 1, 2 and 3 -->
                </xsl:if>
                <!-- Do this for every node -->
            </xsl:for-each>
        </xsl:template>
    </xsl:stylesheet>
    
    0 讨论(0)
  • 2020-11-29 10:24

    In my case I needed total of boxes in the shipment, this helped

        <xsl:for-each select="ShippingConfirmation/Details/LicensePlates/LicensePlate">
                <xsl:if test="position()=last()">
                    <xsl:value-of select="position()"/> 
                </xsl:if>
        </xsl:for-each>
    
    0 讨论(0)
提交回复
热议问题