Re: [xsl] Create xml file with recursive childnodes

Subject: Re: [xsl] Create xml file with recursive childnodes
From: chun ji <cji_work@xxxxxxxxx>
Date: Wed, 13 Aug 2008 14:03:37 -0700 (PDT)
Hi Mukul, 
thank you for 2 solutions. But I see an issue for the
second one if the root obj has more that 1 child. 

For example, if the input xml is : 
"
<Objs>
  <obj name="a" child="b"/>
  <obj name="b" child="c"/>
  <obj name="b" child="d"/>
  <obj name="c" child="e"/>
  <obj name="b" child="f"/>
  <obj name="a" child="u"/>
</Objs>
"
, I get such results

" 
<?xml version="1.0" encoding="UTF-8"?>
<Obj name="a a">
   <Obj name="b">
      <Obj name="c">
         <Obj name="e"/>
      </Obj>
      <Obj name="d"/>
      <Obj name="f"/>
   </Obj>
</Obj>
".  


Regards, 



Chun 






--- Mukul Gandhi <gandhi.mukul@xxxxxxxxx> wrote:

> Here is a slightly better solution.
> 
> <xsl:stylesheet
> xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
>                        version="2.0">
> 
> <xsl:output method="xml" indent="yes" />
> 
> <xsl:template match="Objs">
>   <xsl:variable name="start" select="obj[not(@name =
> ../obj/@child)]" />
>   <Obj name="{$start/@name}">
>     <xsl:choose>
>       <xsl:when test="not(obj[@name =
> $start/@child])">
>         <Obj name="{$start/@child}" />
>       </xsl:when>
>       <xsl:otherwise>
>         <xsl:call-template name="performGrouping">
>           <xsl:with-param name="list"
> select="obj[@name = $start/@child]" />
>         </xsl:call-template>
>       </xsl:otherwise>
>     </xsl:choose>
>   </Obj>
> </xsl:template>
> 
> <xsl:template name="performGrouping">
>   <xsl:param name="list" />
> 
>   <xsl:for-each-group select="$list"
> group-by="@name">
>     <Obj name="{current-grouping-key()}">
>       <xsl:for-each select="current-group()">
>         <xsl:variable name="child" select="@child"
> />
>         <xsl:choose>
>           <xsl:when test="not(../obj[@name =
> $child])">
>             <Obj name="{$child}" />
>           </xsl:when>
>           <xsl:otherwise>
>             <xsl:call-template
> name="performGrouping">
> 	<xsl:with-param name="list" select="../obj[@name =
> $child]" />
>             </xsl:call-template>
>           </xsl:otherwise>
>         </xsl:choose>
>       </xsl:for-each>
>     </Obj>
>   </xsl:for-each-group>
> </xsl:template>
> 
> </xsl:stylesheet>
> 
> The stylesheet I earlier posted did execution in two
> pass. This one
> does the whole processing in a single pass.
> 
> On Sat, Aug 9, 2008 at 10:44 AM, Mukul Gandhi
> <gandhi.mukul@xxxxxxxxx> wrote:
> > The following stylesheet works ...
> 
> -- 
> Regards,
> Mukul Gandhi

Current Thread