RE: [xsl] building hierarchy from path string

Subject: RE: [xsl] building hierarchy from path string
From: Joshua.Kuswadi@xxxxxxxxxxxxxxxxxxxx
Date: Wed, 5 Dec 2001 12:00:00 +1100
Hi John-Mason,

No offense intended, but I didn't try reading through your stylesheet. Instead I attempted solving your problem from scratch. Anyway, I came up with the following stylesheet which did transform your input to produce your output.

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>
 <xsl:output method="xml" omit-xml-declaration="yes"/>
 <xsl:template match="/tree">
  <xsl:apply-templates select="node[substring(@path, 3) = '0000']" mode="depth1" />
 </xsl:template>
	
 <xsl:template match="node" mode="depth1">
  <xsl:variable name="path1" select="substring(@path, 1, 2)" />
  <node name="{@name}">
   <xsl:apply-templates select="//node[substring(@path, 1, 2) = $path1][substring(@path, 3, 2) != '00'][substring(@path, 5) = '00']" mode="depth2"/>
  </node>
 </xsl:template>
 <xsl:template match="node" mode="depth2">
  <xsl:variable name="path2" select="substring(@path, 1, 4)" />
  <node name="{@name}">
   <xsl:apply-templates select="//node[substring(@path, 1, 4) = $path2][substring(@path, 5) != '00']" mode="depth3"/>
  </node>
 </xsl:template>
 <xsl:template match="node" mode="depth3">
  <node name="{@name}" />
 </xsl:template>
</xsl:stylesheet>

I'm sure it could be tidied up or made more generic, but you only have three levels deep, then this will work.

HTH,
Joshua

> -----Original Message-----
> From: John-Mason P. Shackelford [mailto:john-mason@xxxxxxxxxxxxxxx]
> Sent: Wednesday,5 December 2001 11:14
> To: XSL-List@xxxxxxxxxxxxxxxxxxxxxx
> Subject: [xsl] building hierarchy from path string
> 
> 
> 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
> 
> 

------------------------------------------------------------------------------
This message and any attachment is confidential and may be privileged or otherwise protected from disclosure.  If you have received it by mistake please let us know by reply and then delete it from your system; you should not copy the message or disclose its contents to anyone.





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


Current Thread