Looping using for-each
Iterating over a set of nodes is easily done using the
for-each control loop structure. E.g.
<!-- Using for-each -->
<table style="width:300px;">
<xsl:for-each select="$currentPage/node">
<tr><td>
<xsl:if test="position() mod 2 = 0">
<xsl:attribute name="bgcolor">silver</xsl:attribute>
</xsl:if>
<xsl:value-of select="@nodeName"/>
</td></tr>
</xsl:for-each>
</table>
The result looks like this:
My foo image |
My bar blabla |
This and that |
Some other type |
Looping using template matching
Another way to do looping is by matching nodes
on templates, which is quite handy in some
situations. E.g.
<!-- Using template match -->
<table style="width:300px;">
<xsl:apply-templates select="$currentPage/node" />
</table>
</xsl:template>
<xsl:template match="node">
<tr>
<xsl:value-of select="@nodeName"/>
</tr>
</xsl:template>
<xsl:template match="node[@nodeTypeAlias = 'SnippetTestData']">
<tr><td>
<xsl:if test="position() mod 2 = 0">
<xsl:attribute name="bgcolor">silver</xsl:attribute>
</xsl:if>
My special-handling <xsl:value-of select="@nodeName"/>
</td></tr>
</xsl:template>
<xsl:template match="node[@nodeTypeAlias = 'SnippetTestData2']">
<tr><td>
<xsl:if test="position() mod 2 = 0">
<xsl:attribute name="bgcolor">silver</xsl:attribute>
</xsl:if>
My other-type-special-handling <xsl:value-of select="@nodeName"/>
</td></tr>
</xsl:template>
The result looks like this:
My special-handling My foo image |
My special-handling My bar blabla |
My special-handling This and that |
My other-type-special-handling Some other type |
Looping using recursion (call-template)
Often you want to iterate over a variable, but xslt variables
being static kind of limits the fun a bit. One workaround is to
call templates recursively.
The typical Fibonacci example is like this:
<!-- Using call-template -->
<table><tr><td>
<xsl:call-template name="Fibonacci">
<xsl:with-param name="prev" select="1" />
<xsl:with-param name="next" select="1" />
<xsl:with-param name="itemsLeft" select="10" />
</xsl:call-template>
</td></tr></table>
</xsl:template>
<xsl:template name="Fibonacci">
<xsl:param name="prev"/>
<xsl:param name="next"/>
<xsl:param name="itemsLeft"/>
<xsl:value-of select="$prev"/><br/>
<xsl:if test="$itemsLeft > 0">
<xsl:call-template name="Fibonacci">
<xsl:with-param name="prev" select="$next" />
<xsl:with-param name="next" select="$prev+$next" />
<xsl:with-param name="itemsLeft" select="$itemsLeft - 1" />
</xsl:call-template>
</xsl:if>
</xsl:template>
The result looks like this: