[xsl] generic grouping without nesting for-each-group?

Subject: [xsl] generic grouping without nesting for-each-group?
From: James Cummings <james+xsl@xxxxxxxxxxxxxxxxx>
Date: Wed, 28 Jul 2010 14:12:43 +0100
Hiya,

I'm trying to process some very flat XML which looks something like:

===
<body>
<head level="1">one</head>
   <p>test</p>
   <p>test</p>
<head level="3">two</head>
   <p>test</p>
   <p>test</p>
<head level="2">three</head>
   <p>test</p>
   <p>test</p>
</body>
===

(But for this case these could easily have been <h1> <h3> and <h2>)

What I want to do, predictably, is give nested structure to this using
@level and get something like:

===
<body>
<div>
  <head level="1>one</head>
  <p>test</p><p>test</p>
  <div>
    <div><head level="3">two</head>
    <p>test</p><p>test</p>
    </div>
   </div>
   <div>
   <head level="2">three</head>
   <p>test</p><p>test</p>
   </div>
</div>
</body>
====
(i.e. notice the extra blank encompassing div around the level 3 division.)

Now, I know what you are going to say, if I nest inside each other 3
xsl:for-each-group's the outside one looking for head/@level='1', the
middle one looking for head/@level='2', and the last looking for
head/@level='3' it should just work.  Well, except here one of the
groups is implicit... a level 2 needs to be created around the level
3...so I'm not sure entirely how to handle that? (Suggestions
appreciated).

However, the real reason for posting is it strikes me that this must
be such a general purpose use-case that there probably is some way to
do this generically. (I.e. not have nested xsl:for-each-group elements
explicitly for each level) And instead that in processing <head>
elements it might be possible to group by itself and simultaneously
figure out at what depth or how many levels to create.   i.e. if I
added a "<head level="7">test</head><p>test</p><p>test</p>" in between
the 3 and the 2 level it would make a whole bunch of otherwise
content-less nodes surrounding that <head> and the next one. Am I
being daft? Should I just hard-code each level of grouping?

All my problems seem to always be grouping ones,[1]
-James

[1] In life as well I expect.

Current Thread