2010-09-14 179 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>