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="{(_at_)child}" />
</xsl:for-each>
<xsl:call-template name="makeTree">
<xsl:with-param name="list" select="obj[(_at_)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[(_at_)name = $child])">
<Obj name="{$child}" />
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="makeTree">
<xsl:with-param name="list" select="../obj[(_at_)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(_at_)yahoo(_dot_)com> 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(_dot_)mukul(_at_)gmail(_dot_)com> 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[(_at_)name =
$start/@child])">
<Obj name="{$start/@child}" />
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="performGrouping">
<xsl:with-param name="list"
select="obj[(_at_)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[(_at_)name =
$child])">
<Obj name="{$child}" />
</xsl:when>
<xsl:otherwise>
<xsl:call-template
name="performGrouping">
<xsl:with-param name="list" select="../obj[(_at_)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(_dot_)mukul(_at_)gmail(_dot_)com> wrote:
The following stylesheet works ...
--
Regards,
Mukul Gandhi
--
Regards,
Mukul Gandhi
--~------------------------------------------------------------------
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--