Re: [xsl] xslt for hierarchical data

Subject: Re: [xsl] xslt for hierarchical data
From: andrew welch <andrew.j.welch@xxxxxxxxx>
Date: Wed, 11 Jan 2006 13:09:19 +0000
On 1/11/06, Jody Robert Ford <jody.r.ford@xxxxxxxxx> wrote:
> Given a data structure:
>
>
>
> <record id=1 parent="Jack" parentid=0>Jack Jr</record>
>
> <record id=4 parent="Jack" parentid=1>William</record>
>
> <record id=3 parent="Jack Jr" parentid=1>Jack III</record>
>
> <record id=7 parent="William" parentid=4>William Jr.</record>
>
> <record id=9 parent="William Jr" parentid=7>William III</record>
>
> <record id=11 parent="William III" parentid=9>William IV</record>
>
>
>
> How do I get.
>
>
>
> Jack, 0
>
>             Jack Jr., 1
>
>                         Jack III, 3
>
>             William, 4
>
>                         William Jr., 7
>
>                                     William III, 9
>
>                                                 William IV, 11
>
>
>
> Special problems.
>
> The number of generations can be infinite.
> Please note I don't have a Jack record, but I need to display Jack.
(Logical
> root Record)
> Please note some parent records can be physical records too.

I'm not sure your output is correct there - shouldn't William and Jack
III have the same parent?

Making that assumption, this stylesheet:

<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>
<xsl:output indent="yes"/>

<xsl:key name="records-by-parent-id" match="record" use="@parentid"/>

<xsl:template match="/">
	<node>
		<name>Jack, 0</name>
		<xsl:apply-templates select="key('records-by-parent-id', '0')"/>
	</node>
</xsl:template>

<xsl:template match="record">
	<node>
		<name><xsl:value-of select="concat(., ', ', @id)"/></name>
		<xsl:apply-templates select="key('records-by-parent-id', @id)"/>
	</node>
</xsl:template>
</xsl:stylesheet>

Applied to this XML:

<root>
	<record id="1" parent="Jack" parentid="0">Jack Jr</record>
	<record id="4" parent="Jack" parentid="1">William</record>
	<record id="3" parent="Jack Jr" parentid="1">Jack III</record>
	<record id="7" parent="William" parentid="4">William Jr.</record>
	<record id="9" parent="William Jr" parentid="7">William III</record>
	<record id="11" parent="William III" parentid="9">William IV</record>
</root>

Gives this result:

<node>
   <name>Jack, 0</name>
   <node>
      <name>Jack Jr, 1</name>
      <node>
         <name>William, 4</name>
         <node>
            <name>William Jr., 7</name>
            <node>
               <name>William III, 9</name>
               <node>
                  <name>William IV, 11</name>
               </node>
            </node>
         </node>
      </node>
      <node>
         <name>Jack III, 3</name>
      </node>
   </node>
</node>

cheers
andrew

Current Thread