[xsl] building hierarchy from path string

Subject: [xsl] building hierarchy from path string
From: "John-Mason P. Shackelford" <john-mason@xxxxxxxxxxxxxxx>
Date: Tue, 04 Dec 2001 18:14:22 -0600
Greetings all.

I've spent the day trying to write a transformation that will take:

<tree>
 <node depth="0" OID="1" name="Animals" path="100000" />
 <node depth="1" OID="2" name="Reptile" path="102000" />
 <node depth="2" OID="5" name="Snake" path="102010" />
 <node depth="2" OID="6" name="Crock" path="102020" />
 <node depth="2" OID="7" name="Gator" path="102030" />
 <node depth="1" OID="3" name="Bird" path="103000" />
 <node depth="1" OID="4" name="Mamal" path="103000" />
</tree>

and give me:

<tree>
   <node name="Animals">
       <node name="Reptile">
           <node name="Snake" />
           <node name="Crock" />
           <node name="Gator" />
       </node>
   <node name="Bird />
   <node name="Mamal" />
</tree>

I use the depth & path attributes to tell me how the hierarchy is to be built. The path attribute is a sort order and the depth attribute (actually just durived from the path) tells me how deep in the hierarchy the particular node is. The approach I have been working with uses for-next & recursion, and while it will build the hierarchy properly 'til snake, I am having trouble figuring out how to make the recusion unwind properly and pick up the shallower elements. Should I be using the Muenchian technique? How would I implement it here?

The path string is my major asset, I built the depth only to that I wouldn't have to parse the path in my XSLT.

The following demonstates that I am on the wrong track.... :)

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>
<xsl:output method="text/xml" indent="yes" />
<!-- main page -->
<xsl:template match="/tree">
<tree>
<xsl:apply-templates />
</tree>
</xsl:template>
<!-- loop through nodes -->
<xsl:template match="//node[1]">
<xsl:call-template name="treeBuilder">
<xsl:with-param name="nodeElement" select="."/>
</xsl:call-template>
</xsl:template>
<!-- treeBuilder Template -->
<xsl:template name="treeBuilder">
<xsl:param name="nodeElement" />
<!-- start the element and add some attributes -->
<xsl:element name="node">
<xsl:attribute name="name">
<xsl:value-of select="$nodeElement/@name"/>
</xsl:attribute>
<xsl:attribute name="depth">
<xsl:value-of select="$nodeElement/@depth"/>
</xsl:attribute>
<!-- do we need to include elements as part of this one? -->
<xsl:if test="$nodeElement/following::node[position()=1]/@depth &gt; $nodeElement/@depth">
<xsl:call-template name="treeBuilder">
<xsl:with-param name="nodeElement" select="$nodeElement/following-sibling::node[position()=1]"/>
</xsl:call-template>
</xsl:if>
</xsl:element>
</xsl:template>
</xsl:stylesheet>



Any pointers would be much appreciated.


John-Mason
--
http://john-mason.shackelford.org


XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list



Current Thread