xsl-list
[Top] [All Lists]

RE: nesting flat XML based on attribute value.

2005-12-14 04:46:49

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.

Then your template rule for the "ch" element (which you haven't shown us,
and which I didn't actually write for you) appears not to be selecting the
"top-level" sections, but is actually processing all of the sections.

I didn't supply this code because I don't know your data well enough. It
might be that all sec elements with an 8-character id value are top-level,
or the rule might be more complicated.

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


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