RE: [xsl] Create xml file with recursive childnodes

Subject: RE: [xsl] Create xml file with recursive childnodes
From: "Michael Kay" <mike@xxxxxxxxxxxx>
Date: Fri, 8 Aug 2008 09:16:42 +0100
Do this as a standard recursive descent of the input tree using
xsl:apply-templates, but with one exception: instead of processing the
physical XML children, you process the logical children selected using the
foreign key relationship.

Usually in this problem elements have a pointer to their parent node, in
your case you have a pointer to each of the children, which makes it a
little more difficult, but not much.

<xsl:key name="nameKey" match="obj" use="@name"/>

<xsl:template match="obj">
  <Obj name="@name">
    <xsl:for-each select="key('nameKey', @name)">
      <xsl:apply-templates select="key('nameKey', @child)"/>
    </xsl:for-each>
  </Obj>
</xsl:template>

Or you could condense it:

<xsl:template match="obj">
  <Obj name="@name">
      <xsl:apply-templates select="key('nameKey', @name)/key('nameKey',
@child)"/>
  </Obj>
</xsl:template>

but I thought that might be a bit confusing!

Of course, you have to start by calling apply-templates on the "logical
root" of the tree.

Michael Kay
http://www.saxonica.com/
 

> -----Original Message-----
> From: chun ji [mailto:cji_work@xxxxxxxxx] 
> Sent: 08 August 2008 00:31
> To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
> Subject: [xsl] Create xml file with recursive childnodes 
> 
> Hi all, 
> 
> I have been thinking this for days, but still not sure what 
> are the best way to fix it. ( I am using Saxon 2.0 on Window 
> XP and Linux Box. JDK version is 1.6.0 )
> 
> 
> The input XML file is something as:   
> " 
> <Objs> 
>     <obj name="a" child="b"/>
>     <obj name="b" child="c"/>
>     <obj name="b" child="d"/>
>     <obj name="c" child="e"/>
> </Objs>
> ". let's say that xml file has ONLY 1 root node.  
>  
> The output XML file would be: 
> "
> <Obj name="a">
>    <Obj name="b">
>        <Obj name="c">
>           <Obj name="e"/>
>        </Obj>
>        <Obj name="d"/>
>    </Obj>
> </Obj>
> "
> 
> In my opinion, the XSL file would be something as: 
> " 
>   ...
> 
>   <xsl:template match="/">
>          <xsl:value-of select="dumpChildNode(?,...)"/>
>   </xsl:template>
> 
>    <xsl:function name="dumpChildNode" as="...">
>        <xsl:param name="name" .../>
>        <xsl:param name="?" .../>
>        
>        <Obj><xsl:attribute name="name">
>               <xsl:value-of select="@name"/>
>             </xsl:attribute>
> 
>        // Find the child node(s) and call the
> dumpChildNode(..)
>        ....?
>        ....?
>        <xsl:value-of select="dumpChildNode(?,)"/>
>        <Obj>
>  </xsl:function>
> </xsl:stylesheet>
> " 
> 
> Does someone know how to finish the rest of code? Or you have 
> a better idea to solve the whole problem. 
> 
> 
> 
> Thanks a lot 
> 
> 
> Chun  

Current Thread