递归循环XSLT

时间:2010-09-14 13:01:16

标签: 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 ....)

非常感谢,

中号

3 个答案:

答案 0 :(得分: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崩溃堆栈溢出(与Saxon 6.5.4一样),即使count = 1000

答案 1 :(得分: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>

答案 2 :(得分: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>