RE: [xsl] nesting flat XML based on attribute value.

Subject: RE: [xsl] nesting flat XML based on attribute value.
From: "Michael Kay" <mike@xxxxxxxxxxxx>
Date: Tue, 13 Dec 2005 17:47:28 -0000
The key to this is to do a recursive descent using xsl:apply-templates, but
instead of selecting the physical children of the current node in the XML
tree as you normally would, you select the *logical* children, for example

<xsl:template match="sec">
<xsl:copy>
  <xsl:apply-templates select=
     "//sec[string-length(@id)=string-length(current()/@id)+2 and
starts-with(@id, current()/@id)]"/>
</xsl:copy>
</xsl:template>

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



> -----Original Message-----
> From: David Holden [mailto:dh@xxxxxxxx]
> Sent: 13 December 2005 17:39
> To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
> Subject: [xsl] nesting flat XML based on attribute value.
>
>
>
> Hello,
>
>  I'm not sure whether I'm being dumb or not here but I'm
> stuck on converting a
> flat structure to a nested structure.
>
> the flat structure is like this:-
>
> <?xml version="1.0 " encoding="US-ASCII"?>
> <doc>
>   <ch id="1o1">
>     <sec id="sec1o1o1" fpage="3" lpage="5" />
>     <sec id="sec1o1o1o1" fpage="3" lpage="3"/>
>     <sec id="sec1o1o1o2" fpage="3" lpage="4"/>
>     <sec id="sec1o1o1o3" fpage="4" lpage="4"/>
>     <sec id="sec1o1o1o4" fpage="4" lpage="5"/>
>     <sec id="sec1o1o1o5" fpage="5" lpage="5"/>
>     <sec id="sec1o1o2" fpage="5" lpage="7"/>
>     <sec id="sec1o1o2o1" fpage="5" lpage="5"/>
>     <sec id="sec1o1o2o2" fpage="5" lpage="5"/>
>     <sec id="sec1o1o2o3" fpage="5" lpage="6"/>
>     <sec id="sec1o1o2o4" fpage="6" lpage="7"/>
>     <sec id="sec1o1o2o4o1" fpage="6" lpage="6"/>
>     <sec id="sec1o1o2o4o2" fpage="6" lpage="6"/>
>     <sec id="sec1o1o2o4o3" fpage="6" lpage="7"/>
>     <sec id="sec1o1o3" fpage="7" lpage="10"/>
>     <sec id="sec1o1o3o1" fpage="7" lpage="7"/>
>     <sec id="sec1o1o3o1o1" fpage="7" lpage="7"/>
>   </ch>
> </doc>
>
> I would like to get to
>
> <?xml version="1.0" encoding="US-ASCII"?>
> <doc>
>   <ch id="1o1">
>     <sec id="sec1o1o1" fpage="3" lpage="5">
>       <sec id="sec1o1o1o1" fpage="3" lpage="3"/>
>       <sec id="sec1o1o1o2" fpage="3" lpage="4"/>
>       <sec id="sec1o1o1o3" fpage="4" lpage="4"/>
>       <sec id="sec1o1o1o4" fpage="4" lpage="5"/>
>       <sec id="sec1o1o1o5" fpage="5" lpage="5"/>
>     </sec>
>     <sec id="sec1o1o2" fpage="5" lpage="7">
>       <sec id="sec1o1o2o1" fpage="5" lpage="5"/>
>       <sec id="sec1o1o2o2" fpage="5" lpage="5"/>
>       <sec id="sec1o1o2o3" fpage="5" lpage="6"/>
>       <sec id="sec1o1o2o4" fpage="6" lpage="7">
>         <sec id="sec1o1o2o4o1" fpage="6" lpage="6"/>
>         <sec id="sec1o1o2o4o2" fpage="6" lpage="6"/>
>         <sec id="sec1o1o2o4o3" fpage="6" lpage="7"/>
>       </sec>
>     </sec>
>     <sec id="sec1o1o3" fpage="7" lpage="10">
>       <sec id="sec1o1o3o1" fpage="7" lpage="7">
>         <sec id="sec1o1o3o1o1" fpage="7" lpage="7"/>
>       </sec>
>     </sec>
>   </ch>
> </doc>
>
> i.e.  both the nesting "level" and "order" are in the id attribute.
>
> any tips appreciated.
>
>  Dave.

Current Thread