This is the mail archive of the
xsl-list@mulberrytech.com
mailing list .
Re: Tree from a flat list - beginner's question
- To: xsl-list at lists dot mulberrytech dot com
- Subject: [xsl] Re: Tree from a flat list - beginner's question
- From: Dimitre Novatchev <dnovatchev at yahoo dot com>
- Date: Fri, 5 Oct 2001 05:06:06 -0700 (PDT)
- Reply-To: xsl-list at lists dot mulberrytech dot com
> How can I build the corresponding XML tree from a flat
> element-elementParent list if I do not know
> how many levels will I have:
>
> <root>
> <row id=100 parentid=0 name=A/>
> <row id=101 parentid=100 name=A1/>
> <row id=102 parentid=100 name=A2/>
> <row id=103 parentid=101 name=A11/>
> <row id=110 parentid=103 name=A111/>
> <row id=111 parentid=110 name=A1111/>
> <row id=120 parentid=102 name=A21/>
> <root/>
The above is not well-formed xml document! Should be:
<root>
<row id="100" parentid="0" name="A"/>
<row id="101" parentid="100" name="A1"/>
<row id="102" parentid="100" name="A2"/>
<row id="103" parentid="101" name="A11"/>
<row id="110" parentid="103" name="A111"/>
<row id="111" parentid="110" name="A1111"/>
<row id="120" parentid="102" name="A21"/>
</root>
Here's one way to construct the corresponding hierarchy:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes" omit-xml-declaration="yes"/>
<xsl:key name="kRow" match="row" use="@parentid"/>
<xsl:variable name="manySpaces" select="' '"/>
<xsl:variable name="linkList" select="/root/row" />
<xsl:template match="/">
<xsl:call-template name="constructHierarchy"/>
</xsl:template>
<xsl:template name="constructHierarchy">
<xsl:for-each select="key('kRow', '0')">
<xsl:call-template name="makeElement">
<xsl:with-param name="pElement" select="."/>
<xsl:with-param name="indent" select="0"/>
</xsl:call-template>
</xsl:for-each>
</xsl:template>
<xsl:template name="makeElement">
<xsl:param name="pElement" select="/.."/>
<xsl:param name="indent" select="0"/>
<xsl:text>
</xsl:text>
<xsl:value-of select="substring($manySpaces, 1, $indent)"/>
<xsl:element name="{$pElement/@name}">
<xsl:for-each select="key('kRow', $pElement/@id)">
<xsl:call-template name="makeElement">
<xsl:with-param name="pElement" select="."/>
<xsl:with-param name="indent" select="$indent + 2"/>
</xsl:call-template>
</xsl:for-each>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
The result of the transformation is:
<A>
<A1>
<A11>
<A111>
<A1111/>
</A111>
</A11>
</A1>
<A2>
<A21/>
</A2>
</A>
Hope this helped.
Cheers,
Dimitre Novatchev.
__________________________________________________
Do You Yahoo!?
NEW from Yahoo! GeoCities - quick and easy web site hosting, just $8.95/month.
http://geocities.yahoo.com/ps/info1
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list