[xsl] Grouping lists from flat to nested

Subject: [xsl] Grouping lists from flat to nested
From: Stefanie Haupt <st.haupt@xxxxxxxxx>
Date: Mon, 31 Jan 2011 13:18:10 +0100
Dear list,

I'm trying to group list items from flat xml to a nested tree.
I've read and searched a lot and adapted a snippet but I can't get it
to do what I really want.

This is my input at that state of the transformation (working on a
variable here):
<variable>
<p level="0">Der als Filmregisseur  <hi rend="bo">Alan Smithee</hi>
ist ein.. </p>
<p level="0">Das Pseudonym.. .</p>
<p level="0">Der Regisseur...</p>
<head2 level="0">Wissenswertes</head2>
<item level="0" type="ul">Alternative Schreibweisen..</item>
<item level="0" type="ul">Eine alternative Theorie...</item>
<item level="0" type="ul">Zu den ... </item>
<item level="1" type="ul">Don  </item>
<item level="1" type="ul">David Lynch </item>
<item level="1" type="ul">Chris Christensen </item>
<item level="1" type="ul">Stuart Rosenberg</item>
<item level="1" type="ul">Richard C. Sarafian</item>
<item level="1" type="ul">Dennis Hopper  </item>
<item level="2" type="ul"> level 3 ulitem</item>
<item level="1" type="ul">Arthur Hiller (fC<r ), </item>
<item level="1" type="ul">Rick Rosenthal (Birds II) und </item>
<item level="1" type="ul">Kevin Yagher </item>
<item level="0" type="ul">Zu den Drehbuchautoren </item>
<item level="1" type="ul">Sam Raimi und Ivan Raimi </item>
<head2 level="0">Weblinks</head2>
</variable

And this is the desired output:
  <p level="0">Der als Filmregisseur <hi rend="bo">Alan Smithee</hi>
ist ein.. </p>
  <p level="0">Das Pseudonym.. .</p>
  <p level="0">Der Regisseur...</p>
  <head2 level="0">Wissenswertes</head2>
  <list type="ul">
    <item>Alternative Schreibweisen..</item>
    <item>Eine alternative Theorie...</item>
    <item>Zu den ... </item>
    <list type="ul">
      <item>Don </item>
      <item>David Lynch </item>
      <item>Chris Christensen </item>
      <item>Stuart Rosenberg</item>
      <item>Richard C. Sarafian</item>
      <item>Dennis Hopper </item>
      <list type="ul">
        <item> level 3 ulitem</item>
      </list>
      <item>Arthur Hiller (fC<r ), </item>
      <item>Rick Rosenthal (Birds II) und </item>
      <item>Kevin Yagher </item>
    </list>
    <item>Zu den Drehbuchautoren </item>
    <list type="ul">
      <item>Sam Raimi und Ivan Raimi</item>
    </list>
  </list>
  <head2 level="0">Weblinks</head2>

Currently I'm stuck with this attempt (excerpt from my xsl) - it's
based on what Michael Kay described here:
http://www.saxonica.com/papers/ideadb-1.1/mhk-paper.xml:

<xsl:template match=text>
...
...
<xsl:variable name=text2>
...please see up for example
</xsl:variable>

  <xsl:call-template name="process-level">
          <xsl:with-param name="population" select="$text2"/>
          <xsl:with-param name="level" select="0"/>
  </xsl:call-template>
</xsl:template>

  <xsl:template name="process-level">
    <xsl:param name="population" required="yes" as="element()*"/>
    <xsl:param name="level" required="yes" as="xs:integer"/>
    <xsl:for-each-group select="$population"
      group-starting-with="*[xs:integer(@level) eq $level]">

      <xsl:choose>
        <xsl:when test="name()='item'">
          <list type="{@type}">
            <item>
              <xsl:value-of select="normalize-space(.)"/>
            </item>
            <xsl:call-template name="process-level">
              <xsl:with-param name="population"
                select="current-group()[position() != 1]"/>
              <xsl:with-param name="level" select="$level + 1"/>
            </xsl:call-template>
          </list>
        </xsl:when>

        <xsl:otherwise>
          <xsl:copy-of select="."/>
          <xsl:call-template name="process-level">
            <xsl:with-param name="population"
              select="current-group()[position() != 1]"/>
            <xsl:with-param name="level" select="$level + 1"/>
          </xsl:call-template>
        </xsl:otherwise>
      </xsl:choose>

    </xsl:for-each-group>

  </xsl:template>

The current result snippet looks like this:

  <p level="0">Der als Filmregisseur <hi rend="bo">Alan Smithee</hi></p>
  <p level="0">Das Pseudonym </p>
  <p level="0">Der Regisseur </p>
  <head2 level="0">Wissenswertes</head2>
  <list type="ul">
    <item>Alternative Schreibweisen </item>
  </list>
  <list type="ul">
    <item>Eine alternative Theorie </item>
  </list>
  <list type="ul">
    <item>Zu den </item>
    <list type="ul">
      <item>Don </item>
    </list>
    <list type="ul">
      <item>David Lynch </item>
    </list>
    <list type="ul">
      <item>Chris Christensen </item>
    </list>
    <list type="ul">
      <item>Stuart Rosenberg </item>
    </list>
    <list type="ul">
      <item>Richard C. Sarafian </item>
    </list>
    <list type="ul">
      <item>Dennis Hopper ,</item>
      <list type="ul">
        <item>level 3 ulitem</item>
      </list>
    </list>
    <list type="ul">
      <item>Arthur Hiller (fC<r ),</item>
    </list>
    <list type="ul">
      <item>Rick Rosenthal (Birds II) und</item>
    </list>
    <list type="ul">
      <item>Kevin Yagher </item>
    </list>
  </list>
  <list type="ul">
    <item>Zu den Drehbuchautoren</item>
    <list type="ul">
      <item>Sam Raimi und Ivan Raimi </item>
    </list>
  </list>
  <head2 level="0">Weblinks</head2>

As you can see *every* item is wrapped into a list element, apart from
that, it's fairly what I want. I suppose I added a simple logical
error, but I can't get it right. Any help is appreciated.

Kind Regards,
Stefanie

--
Stefanie Haupt, M.A.

Current Thread