2010-09-14 185 views
5

所有,遞歸循環XSLT

我有以下XSLT

<xsl:template name="loop"> 
    <xsl:param name="count" select="1"/> 
    <xsl:if test="$count > 0"> 
     <xsl:text> </xsl:text> 
     <xsl:value-of select="$count"/> 
     <xsl:call-template name="loop"> 
      <xsl:with-param name="count" select="$count - 1"/> 
     </xsl:call-template> 
    </xsl:if>  
</xsl:template> 

調用它的方法是:

<xsl:call-template name="loop 
    <xsl:with-param name="count" select="100"/> 
</xsl:call-template> 

在它顯示從100到0和空間號碼的那一刻它們之間。 (100 99 98 97 .....)

我該如何改變它來做相反的事情? (1 2 3 4 ....)

非常感謝,

中號

+0

好問題(+1)。請參閱我的答案,以獲得比當前選定的解決方案更短,效率更高的解:) – 2010-09-14 13:26:30

回答

6

只需改變模板內的順序爲:

<xsl:template name="loop"> 
    <xsl:param name="count" select="1"/> 

    <xsl:if test="$count > 0"> 
     <xsl:call-template name="loop"> 
      <xsl:with-param name="count" select="$count - 1"/> 
     </xsl:call-template> 

     <xsl:value-of select="$count"/> 
     <xsl:text> </xsl:text> 

    </xsl:if>  
</xsl:template> 
+0

好但不是太可靠和有效的解決方案。 – 2010-09-14 13:40:16

9

使用

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output method="text"/> 

    <xsl:template match="/"> 
     <xsl:call-template name="loop"> 
     <xsl:with-param name="count" select="100"/> 
     </xsl:call-template> 
    </xsl:template> 

    <xsl:template name="loop"> 
     <xsl:param name="count" select="1"/> 
     <xsl:param name="limit" select="$count+1"/> 

     <xsl:if test="$count > 0"> 
      <xsl:text> </xsl:text> 
      <xsl:value-of select="$limit - $count"/> 
      <xsl:call-template name="loop"> 
       <xsl:with-param name="count" select="$count - 1"/> 
       <xsl:with-param name="limit" select="$limit"/> 
      </xsl:call-template> 
     </xsl:if> 
    </xsl:template> 
</xsl:stylesheet> 

執行此轉換時在任何XML文檔(未使用)上,想要的結果是:1至100生成

請注意:該解決方案是尾遞歸與許多XSLT處理器將被優化,使得遞歸消除。這意味着您可以將其與$count設置爲數百萬,而不會發生堆棧溢出或執行緩慢。

非尾遞歸溶液,如@ 0xA3執行的所述一個與堆棧上溢(與撒克遜6.5.4)崩潰即使count = 1000

0

嘗試這一個。

<xsl:template name="loop"> 
    <xsl:param name="inc"/> 
    <xsl:param name="str" select="1"/> 
    <xsl:if test="$str &lt;= $inc"> 
     <xsl:text> </xsl:text> 
     <xsl:value-of select="$str"/> 
     <xsl:call-template name="loop"> 
      <xsl:with-param name="inc" select="$inc"/> 
      <xsl:with-param name="str" select="$str + 1"></xsl:with-param> 
     </xsl:call-template> 
    </xsl:if> 
</xsl:template> 

<xsl:call-template name="loop"> 
    <xsl:with-param name="inc" select="10"/> 
</xsl:call-template>