Re: [xsl] apply-imports and recursion used together

Subject: Re: [xsl] apply-imports and recursion used together
From: Jeni Tennison <jeni@xxxxxxxxxxxxxxxx>
Date: Wed, 5 Mar 2003 18:08:02 +0000
Hi Tom,

> Can someone explain to me the technical reason behind the following:
>
> The following template exists in an imported stylesheet:
>
> <xsl:template match="FORUMTHREADPOSTS" mode="postblocks">
>         <xsl:param name="skip" select="0"/>
>         <xsl:param name="PostRange" select="concat(($skip + 1), ' - ', ($skip + 
> @COUNT))"/>
>         <xsl:param name="postblockon" select="concat($alt_nowshowing, ' ', 
> $PostRange)"/>
>         <xsl:param name="postblockoff" select="concat($alt_show, ' ', 
> $PostRange)"/>
[snip]
>         <xsl:if test="($skip + @COUNT) &lt; @TOTALPOSTCOUNT">
>                 <xsl:apply-templates select="." mode="postblocks">
>                         <xsl:with-param name="skip" select="$skip + @COUNT"/>
>                 </xsl:apply-templates>
>         </xsl:if>
> </xsl:template>
>
> The template works in the way I would expect it. However if an
> apply-imports template is used in the including template I get an
> infinite loop:
>
> <xsl:template match="FORUMTHREADPOSTS" mode="postblocks">
>    <xsl:apply-imports/>
> </xsl:template>

Note that when you apply imports you don't (cannot) pass any
parameters to the imported template. So say the above template gets
called; it calls the imported template and since it's called with no
parameters, the default values are used for those parameters. In
particular, $skip is 0.

$skip of 0 means that the stopping condition in your recursive
template is passed, and templates are applied to the same
<FORUMTHREADPOSTS> element, with $skip adjusted.

But the template that gets used is the one from you *importing*
stylesheet; this ignores the updated value of the $skip parameter and
just applies imports, again with the default values for all the
parameters.

So you get infinite recursion because the $skip parameter gets lost
when you apply imports. In XSLT 2.0, <xsl:apply-imports> can have
<xsl:with-param> children, so you'll be able to do:

<xsl:template match="FORUMTHREADPOSTS" mode="postblocks">
  <xsl:param name="skip" select="0" />
  <xsl:apply-imports>
    <xsl:with-param name="skip" select="$skip" />
  </xsl:apply-imports>
</xsl:template>

which will fix the problem.

Cheers,

Jeni

---
Jeni Tennison
http://www.jenitennison.com/


 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list


Current Thread