views:

49

answers:

2

I'm trying to create something similar to a for-loop with the recursive idiom I've seen across the web. My implementation is with a parameter that tells what to print. I use the Eclipse built-in XSL transformator and I can't for the life of me see why it gives a StackOverflowException:

<!-- 
    Loops recursively to print something the number of times specified with 
    the max parameter. 
    The print parameter tells what to print.
-->
<xsl:template name="loop">
    <xsl:param name="count" select="1"/>
    <xsl:param name="max" />
    <xsl:param name="print" />
    <xsl:if test="not($count = $max)">

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

        <xsl:call-template name="loop">
            <xsl:with-param name="count">
                <xsl:value-of select="$count + 1" />
            </xsl:with-param>
            <xsl:with-param name="max">
                <xsl:value-of select="$max"/>
            </xsl:with-param>
            <xsl:with-param name="print">
                <xsl:value-of select="$print" />
            </xsl:with-param>
        </xsl:call-template>
    </xsl:if>
</xsl:template>

Also, why does $count < $max give invalid Xpath expression?

Thanks in advance.

+3  A: 

Also, why does $count < $max give invalid Xpath expression?

You should use &lt; instead of < symbol.

Andrew Bezzub
Thanks. It works if I use this condition and start with 0, so I assume the infinite recursion has something to do with my previous condition.
pg-robban
+3  A: 

I can't for the life of me see why it gives a StackOverflowException

The check for "stop" in the code is too weak:

<xsl:if test="not($count = $max)">      

This will always be true() if $max is less than $count, if one or both of $max and $count dont have integer values, or if they are undefined.

Also, why does $count < $max give invalid Xpath expression?

You can use:

not($count >= $max)

and thus avoid the need to escape the < character.

Finally, another problem, not directly related to the main issue:

Never specify the (atomic) value of parameter in in the body of <xsl:with-param>, <xsl:param> or <xsl:variable>. This creates an RTF (Result Tree Fragment) and needs conversion to the proper atomic value every time the parameter/variable is referenced. This is inefficient, difficult to read and maintain and may lead to errors.

Instead of:

        <xsl:with-param name="count">               
            <xsl:value-of select="$count + 1" />               
        </xsl:with-param>               

write:

        <xsl:with-param name="count" select="$count + 1" />               
Dimitre Novatchev
Thanks for the thorough explanation.
pg-robban