开发者

Recursive Loop XSLT

All,

I have the below 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>

The way to call it is开发者_JAVA百科:

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

At the moment it displays numbers from 100 to 0 and space between them. (100 99 98 97.....)

How can I change it to do the opposite ? (1 2 3 4....)

Many Thanks,

M


Use:

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

when this transformation is performed on any XML document (not used), the wanted result: 1 to 100 is produced.

Do note: This solution is tail-recursive and with many XSLT processors will be optimized so that recursion is eliminated. This means you can use it with $count set to millions without stack overflow or slow execution.

A non-tail recursive solution, like the one of @0xA3 crashes with stack-overflow (with Saxon 6.5.4) even with count = 1000


Simply change the order inside the template:

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


Try this one.

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜