xsl-list
[Top] [All Lists]

Re: nesting flat XML based on attribute value.

2005-12-14 04:18:36
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(_at_)iucr(_dot_)org]
Sent: 13 December 2005 17:39
To: xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com
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.
-------------------------------------------------------------

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