Looping

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 &gt; 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:

1
1
2
3
5
8
13
21
34
55
89