[xsl] XSL to create nested list items?

Subject: [xsl] XSL to create nested list items?
From: Shawn <sgrover@xxxxxxxxxxxxxx>
Date: Fri, 19 Nov 2004 01:26:10 -0700
Hi there.

I'm new to the list, and a relative newbie to XSL.  I'm able to do the simpler 
things, but am still learning.

At the moment, I'm having problems figuring out how to store menu items in 
XML, then render them in XSL.

I'm trying to get output something like this:

<ul>
  <li>
	One
	<ul>
		<li>One dot One</li>
	</ul>
  </li>
</ul>

Of course, there can be multiple top level items, each of which may have many 
sub items and/or sub-lists.

With regards to the XML, I've tried to create a nested structure something 
like so:

<menu>
  <item>
	<name>One</name>
	<url></url>
	<item>
		<name>One dot One</name>
		<url>http://someplace.com</url>
	</item>
  </item>
</menu>

I like this structure as it directly reflects the menu, but have only had some 
success with the XSL.  I could not get the sub menu items to be treated 
differently - the only way I could make this work was to enclose each <li> 
item in <ul>, and that's not quite what I want.

So I tried to change the XML a bit to something like so:

<menu>
	<item parent="0">
		<id>1</id>
		<name>One</name>
		<url></url>
	</item>
	<item parent="1">
		<id>2</id>
		<name>One dot One</name>
		<url>http://someplace.com</url>
	</item>
</menu>

I have partial success with this method as well, but cannot properly select 
the parent items only (any item with a parent=0), and then create the correct 
sub list.

Here's the XSL I'm currently using:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>
	<xsl:template match="/">
		<xsl:apply-templates/>
	</xsl:template>
	
	<xsl:template match="item[@parent='0']">
		<xsl:call-template name="topitem"/>
	</xsl:template>
	
	<xsl:template name="topitem">
		<xsl:element name="a">
			<xsl:attribute name="href"><xsl:value-of select="url"/></xsl:attribute>
			<xsl:value-of select="name"/>
		</xsl:element>
	</xsl:template>
	
	<xsl:template name="menuitem">
	</xsl:template>
</xsl:stylesheet>

Of course, this doesn't generate my lists yet, but it won't select only the 
top level items either.  For the second template (match="item"), I tried to 
do match="item[parent=0]"  (and [@parent=0] after I changed to try an 
attribute instead of an element).  I eventually figured out I needed 
[@parent='0'], but now I'm stuck getting the sub menus handled properly - I 
don't know how to select only my sub menu items, and have them handled by the 
menuitem template.

So, I'm hoping I can get some pointers from people more knowledgeabe than me.  
The whole idea is to create a nested html list, then apply CSS to it to turn 
it into a navigation menu.  But we would like to use XML to describe the menu 
for easy editing (and possibly generating the XML from a database down the 
road).  I have the feeling I'm making this tougher than it needs to be, 
and/or that I'm missing something stupid.

Thanks in advance for tips or suggestions.  The book I have dives into the 
advanced stuff too quick, and I've only had partial success with Google on 
this particular issue.

Shawn

Current Thread