Alex Rivera | Logout

XSLT templates and recursion

Asked 2010-05-14T15:55:41.607
20

Im new to XSLT and am having some problems trying to format an XML document which has recursive nodes.

My XML Code:

Hopefully my XML shows:

  • All <item> are nested with <items>
  • An item can have either just attributes, or sub nodes
  • The level to which <item> nodes are nested can be infinently deep
<?xml version="1.0" encoding="utf-8" ?> 
- <items>
  <item groupID="1" name="Home" url="//" /> 
- <item groupID="2" name="Guides" url="/Guides/">
- <items>
- <item groupID="26" name="Online-Poker-Guide" url="/Guides/Online-Poker-Guide/">
- <items>
- <item>
  <id>107</id> 
- <title>
- <![CDATA[ Poker Betting - Online Poker Betting Structures
  ]]> 
  </title>
- <url>
- <![CDATA[ /Guides/Online-Poker-Guide/online-poker-betting-structures
  ]]> 
  </url>
  </item>
- <item>
  <id>114</id> 
- <title>
- <![CDATA[ Beginners&#39; Poker - Poker Hand Ranking
  ]]> 
  </title>
- <url>
- <![CDATA[ /Guides/Online-Poker-Guide/online-poker-hand-ranking
  ]]> 
  </url>
  </item>
- <item>
  <id>115</id> 
- <title>
- <![CDATA[ Poker Terms - 4th Street and 5th Street
  ]]> 
  </title>
- <url>
- <![CDATA[ /Guides/Online-Poker-Guide/online-poker-poker-terms
  ]]> 
  </url>
  </item>
- <item>
  <id>116</id> 
- <title>
- <![CDATA[ Popular Poker - The Popularity of Texas Hold&#39;em
  ]]> 
  </title>
- <url>
- <![CDATA[ /Guides/Online-Poker-Guide/online-poker-popularity-texas-holdem
  ]]> 
  </url>
  </item>
- <item>
  <id>364</id> 
- <title>
- <![CDATA[ The Impact of Traditional Poker on Online Poker (and vice versa)
  ]]> 
  </title>
- <url>
Edit
Report

2 Answers

5

You should be able to do this without writing a loop, if I understand your needs correctly.

It's generally better to use a more declarative style, in this instance writing a template matching the <items> tag and converting it to a <ul> and another matching <item> converting it to a <li>. An <xsl:apply-templates/> call inside both templates would supply the recursion.

answered 2010-05-14T16:57:19.833
3

The following stylesheet performs the specified formatting. Note the use of xsl:apply-templates to recurse down the XML tree. See 5.4 Applying Template Rules for more information.

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes"/>
    <xsl:template match="/">
        <xsl:apply-templates select="items"/>
    </xsl:template>

    <xsl:template match="items">
        <ul>
            <xsl:apply-templates select="item" />
        </ul>
    </xsl:template>

    <xsl:template match="item">
        <li>
            <xsl:choose>
                <xsl:when test="@name">
                    <xsl:value-of select="@name"/>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:value-of select="id"/>
                </xsl:otherwise>
            </xsl:choose>
            <xsl:apply-templates select="items" />
        </li>
    </xsl:template>
</xsl:stylesheet>
answered 2010-05-15T06:20:52.577

Your Answer