2012-03-07 25 views
6

我很難分配一個計數器變量並將其遞增,然後檢查XSLT中的某個值。這裏是我的代碼:遞增並檢查XSLT中的計數器變量

<?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:variable name="counter" select="0"/> 
<xsl:template match="/Collection"> 
     <xsl:for-each select="Content"> 
      <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'"> 
          <!-- Increment Counter --> 
          <xsl:value-of select="$counter + 1"/> 
          <!-- Test if Counter < 4 --> 
          <xsl:if test="$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> 

但它似乎沒有增加我的櫃檯,而不是退出時反打3任何幫助?

回答

11

XSL中的'變量'實際上是常量 - 你不能改變它們的值。這:

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

將只輸出的$counter+1

值要做到,你必須使用遞歸循環 - 如:

<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最好是儘量避免循環 - 在大多數爲了避免這種情況,可以編寫XSL,但是我不太瞭解你想要實現哪些功能來爲您提供完整的解決方案。

7

我有同樣的問題。我需要在循環中增加值。所以最簡單的方法是包括撒克遜並使用該價值。

如果使用撒克遜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"> 

如果使用撒克遜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"> 

之後,你可以簡單地使用撒克遜變量:

<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

不幸的是,撒克遜他是限於XSLT 2.0版本,所以你不能用免費版使用此解決方案。 – Hraban 2015-08-27 09:35:41

2

在任何人想要在使用.net(XslCompiledTransform)時都可以使用

<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> 

然後添加一個調用「customCode:AddToCounter()」,然後他們就像常數,你可以這樣寫<xsl:message><xsl:value-of select="customCode:GetCounter()" /> rows remaining.</xsl:message>

+0

好的答案,只是在BizTalk的xslt映射中使用了這個 – basvo 2015-02-25 08:45:26

1

消息我們不能更新xsl:variable。但是我們可以更新dp:local-variables,所以這裏dp:local-variable計數器在開始for循環之前被初始化。每次運行循環計數器加1 更新自己試試這個:

<?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

看起來'dp'命名空間是對IBM DataPower的引用...您在工作表中沒有提及。另外,你的樣式表標籤沒有關閉。即使樣式表標籤已更正,我假設沒有導入命名空間或在IBM設備上運行,「dp」將不起作用...? – 2017-04-17 20:22:11

0

如果你想知道你是在一個for-each循環,您可以使用內置的位置()函數。

<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

在我來說,我需要的總箱在運輸,這有助於

<xsl:for-each select="ShippingConfirmation/Details/LicensePlates/LicensePlate"> 
      <xsl:if test="position()=last()"> 
       <xsl:value-of select="position()"/> 
      </xsl:if> 
    </xsl:for-each>