[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message]

Re: Create xml file with recursive childnodes

Subject: Re: Create xml file with recursive childnodes
From: "Mukul Gandhi" <gandhi.mukul@xxxxxxxxx>
Date: Thu, 14 Aug 2008 09:27:56 +0530
Re:  Create xml file with recursive childnodes
Hi Chun,
  Thanks for pointing the error. Below is the stylesheet, which has this fix ...

<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)]" />
<xsl:variable name="startName" select="distinct-values($start/@name)" />
<Obj name="{$startName}">
   <xsl:for-each select="obj[(@name = $startName) and not(../obj/@name
= @child)]">
     <Obj name="{@child}" />
   </xsl:for-each>
   <xsl:call-template name="makeTree">
     <xsl:with-param name="list" select="obj[@name = $start/@child]" />
   </xsl:call-template>
</Obj>
</xsl:template>


<xsl:template name="makeTree">
  <xsl:param name="list" />

  <Obj name="{$list[1]/@name}">
    <xsl:for-each select="$list">
      <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="makeTree">
            <xsl:with-param name="list" select="../obj[@name = $child]" />
          </xsl:call-template>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:for-each>
  </Obj>
</xsl:template>

</xsl:stylesheet>

I think, we don't really need for-each-group. I have modified the
stylesheet accordingly, using a normal for-each loop.

Kindly do report any bugs in this version, and I'll attempt to solve it.

On 8/14/08, chun ji <cji_work@xxxxxxxxx> wrote:
> 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


-- 
Regards,
Mukul Gandhi

Current Thread

PURCHASE STYLUS STUDIO ONLINE TODAY!

Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced!

Buy Stylus Studio Now

Download The World's Best XML IDE!

Accelerate XML development with our award-winning XML IDE - Download a free trial today!

Don't miss another message! Subscribe to this list today.
Email
First Name
Last Name
Company
Subscribe in XML format
RSS 2.0
Atom 0.3
Site Map | Privacy Policy | Terms of Use | Trademarks
Free Stylus Studio XML Training:
W3C Member
Stylus Studio® and DataDirect XQuery ™are products from DataDirect Technologies, is a registered trademark of Progress Software Corporation, in the U.S. and other countries. © 2004-2013 All Rights Reserved.