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

Subject: Re: [xsl] nesting flat XML based on attribute value.
From: David Holden <dh@xxxxxxxx>
Date: Wed, 14 Dec 2005 11:18:36 +0000
On Tuesday 13 Dec 2005 17:47, Michael Kay wrote:

Thanks a lot Michael, in particular for that select which neatly takes care of
the position and order I was puzzled by.

Unfortunately I'm not quite there yet.

It seems that for each section the recursion groups them nicely but then when
it exist the recursion it applies the same again to <sec> tags that have
already been grouped therefore sec's are getting output twice, e.g.

<?xml version="1.0" encoding="iso-8859-1"?>
<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"/>
...

goes to

<?xml version="1.0"?>
<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>
        <!-- these have already been output -->
        <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"/>

it needs to some how remember what it has already grouped (sorry for the
procedural thinking here.)

This isn't too much of a problem in this case because I can remove those extra
sec tags with a second script based on depth.

   Dave.


> 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.


--
Dr. David Holden.
Please avoid sending me Word or PowerPoint attachments, thanks.
See: <http://www.gnu.org/philosophy/no-word-attachments.html>
Public GPG key available on request.
-------------------------------------------------------------

Current Thread