Re: [xsl] flat xml to full tree with no repeating

Subject: Re: [xsl] flat xml to full tree with no repeating
From: "Anton Triest" <anton@xxxxxxxx>
Date: Wed, 22 Sep 2004 22:01:06 +0200
Hi Steve,

You don't want to group your employees here, you want to nest them. 
Let's start with the top level: the one that doesn't have a manager:

 <xsl:variable name="big-boss-id" select="key('by-manager', '')/uid"/>

Then you can start the tree from there and use apply-templates
on all employees that have the big boss as manager:

 <xsl:template match="employees">
  <nodes>
   <node>
    <top><xsl:value-of select="$big-boss-id"/></top>
    <xsl:apply-templates select="key('by-manager', $big-boss-id)">
     <xsl:sort select="uid"/>
    </xsl:apply-templates>
   </node>
  </nodes>
 </xsl:template>

You now need a template to match="employee", that adds new
employees if he/she is somebody else's manager:

 <xsl:template match="employee">
  <node>
   <bottom><xsl:value-of select="uid"/></bottom>
   <xsl:apply-templates select="key('by-manager', uid)">
    <xsl:sort select="uid"/>
   </xsl:apply-templates>
  </node>
 </xsl:template>

That will keep adding deeper levels recursively, and give you the
output you wanted.

Cheers
Anton


Steve Lenhart wrote:
>
> I have a flat xml file that i'm trying to make into a tree format with 
> out repeats, and still keep all the child nodes.
> 
> the input xml file looks like.....
> 
> <employees>
>     <employee>
>         <uid>ceo</uid>
>         <manager-uid></manager-uid>
>     </employee>
>     <employee>
>         <uid>vp-1</uid>
>         <manager-uid>ceo</manager-uid>
>     </employee>
>     <employee>
>         <uid>vp-2</uid>
>         <manager-uid>ceo</manager-uid>
>     </employee>
>     <employee>
>         <uid>vp-1-secratary</uid>
>         <manager-uid>vp-1</manager-uid>
>     </employee>
>     <employee>
>         <uid>vp-1-assistant</uid>
>         <manager-uid>vp-1</manager-uid>
>     </employee>
>     <employee>
>         <uid>vp-1-secratary2</uid>
>         <manager-uid>vp-1</manager-uid>
>     </employee>
>     <employee>
>         <uid>vp-1-secretary2assistant</uid>
>         <manager-uid>vp-1-secratary2</manager-uid>
>     </employee>
>     <employee>
>         <uid>vp-2-secretary</uid>
>         <manager-uid>vp-2</manager-uid>
>     </employee>
> </employees>
> --------
> 
> id like the output to look like....
> 
> <?xml version="1.0"?>
> <nodes>
>     <node>
>         <top>ceo</top>
>         <node>
>             <bottom>vp-1</bottom>
>             <node>
>                 <bottom>vp-1-assistant</bottom>
>             </node>
>             <node>
>                 <bottom>vp-1-secratary</bottom>
>             </node>
>             <node>
>                 <bottom>vp-1-secratary2</bottom>
>                 <node>
>                     <bottom>vp-1-secretary2assistant</bottom>
>                 </node>
>             </node>
>         </node>
>         <node>
>             <bottom>vp-2</bottom>
>             <node>
>                 <bottom>vp-2-secretary</bottom>
>             </node>
>         </node>
>     </node>
> </nodes>
> -------
> 
> the xslt file im using makes it into a tree but i cant make it do the 
> full grouping that i want. the xsl file looks like.......
> 
> <?xml version='1.0'?>
> <xsl:stylesheet version="1.0" 
> xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>
> <xsl:key name="all-reports" match="employee" use="manager-uid" />
> 
> <xsl:template match="employees">
> <nodes>
>     <xsl:for-each select="employee[generate-id() = 
> generate-id(key('all-reports',manager-uid)[1])]">
>      <xsl:sort select="manager-uid" />
>      <xsl:if test="not(manager-uid = '')">
>        <node>
>         <top><xsl:value-of select="manager-uid" /></top>
>           <xsl:for-each select="key('all-reports', manager-uid)">
>             <xsl:sort select="uid" />
>             <node>
>               <bottom><xsl:value-of select="uid" /></bottom>
>             </node>
>           </xsl:for-each>
>        </node>
>        </xsl:if>
>     </xsl:for-each>
>   </nodes>
> </xsl:template>
> </xsl:stylesheet>
> 
> thanks in advance for your help
> 
> 
> 
> Steve Lenhart <slenhart@xxxxxxxxxxxx>
> Corporate IT Department
> Teleflex Incorporated

Current Thread