[xsl] Iterate through tree structure

Subject: [xsl] Iterate through tree structure
From: jim mcgovern <jim.mcgovern2@xxxxxxxxxxxxxx>
Date: Tue, 31 Mar 2009 16:28:34 +0100
Hi there

Apologies for the duplicate post but I sent this through hotmail
earlier and it stripped the content.  Hopefully this will be more
successful...

Hopefully someone can help me with something that I thought was going
to be straight forward but has been giving me a few problems!

I'm trying to generate navigation from an xml file which is pretty
much as below:-

<dir name="dir1" id="x1">
 <page pname = "page1"></page>
 <dir name="dir2" id="x2">
   <page pname = "page2"></page>
  <dir name="dir3" id="x3">
    <page pname = "page3"></page>
  </dir>
  <dir name="dir4" id="x4">
    <page pname = "page4"></page>
   <dir name="dir5" id="x5">
     <page pname = "page5"></page>
     <page pname = "page6"></page>
    <dir name="dir6" id="x6">
      <page pname = "page6"></page>
    </dir>
   </dir>
  </dir>
 </dir>
</dir>

The above is a snapshot as it can go down "n" levels.  If I'm at page6
then my navigation needs to be:-

<ul>
  <li>dir1</li>
  <li>dir2</li>
  <li>dir4</li>
</ul>
<ul>
  <li>dir5</li>
  <li>dir6</li>
</ul>

What I'm having difficulty with is how to close the opening ul and
open a new ul when I'm a directory up from the directory level I'm
actully on.

A stripped down but working version of What I'm trying is:-

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>
  <xsl:output omit-xml-declaration="yes" method="html" indent="yes"
version="4.0"/>
  <xsl:param name="directoryID" ></xsl:param>
 <xsl:template match="/dir">
  <xsl:call-template name="navigation"></xsl:call-template>
 </xsl:template>

 <xsl:template name="navigation">
  <xsl:element name="ul">
   <xsl:call-template name="nav"></xsl:call-template>
  </xsl:element>
 </xsl:template>

 <xsl:template name="nav">
  <xsl:if test="(descendant-or-self::*[@dirID = $directoryID])">
   <xsl:for-each select="./dir">
    <xsl:if test="(descendant-or-self::*[@dirID = $directoryID])">
     <xsl:element name="li">
      <xsl:value-of select="@name"/>
     </xsl:element>
     <!-- recurse -->
     <xsl:call-template name="nav"></xsl:call-template>
    </xsl:if>
   </xsl:for-each>
  </xsl:if>
 </xsl:template>
</xsl:stylesheet>

Can anyone advise me on how to achieve the formatting where I have 2
sets of ULs? Any pointers much appreciated.

Thanks

Jim

Current Thread