RE: [xsl] grouping list items by attribute

Subject: RE: [xsl] grouping list items by attribute
From: Lynn Alford <lynn.alford@xxxxxxxxxx>
Date: Wed, 05 Oct 2005 15:56:09 +1000
I'm very close to the results I'd like but am hoping for a few pointers to
finish this part of the transformation off.  The answer has to be used by
Xalan - so it must be an xslt1 solution.

Forgive the length of the post and thanks to anyone who can help with
this.  Basically, I can find the list items, determine correctly if they
are ordered or not.  But it's not correctly traversing the list so items
may appear at the same level as sub-items.

The XML looks like

<?xml version="1.0" encoding="UTF-8"?>
<flexiondoc xmlns="http://www.outsideinsdk.com/xmlns/flexiondoc5_1";>

  <content>
    <wp.doc id="ID20" object_id="2147483648">
      <wp.section>
        <tx.p style="ID1d9">List test</tx.p>
        <tx.list style="ID27e">
          <tx.li level="0" number="1.   "><tx.p>Ordered - list
item</tx.p></tx.li>
          <tx.li level="1" number="a.   "><tx.p>Nested list
item</tx.p></tx.li>
          <tx.li level="1" number="b.   "><tx.p>Nested list
item</tx.p></tx.li>
          <tx.li level="2" number="'    "><tx.p>Nested nested list
item</tx.p></tx.li>
          <tx.li level="2" number="'    "><tx.p>And yet
another</tx.p></tx.li>
          <tx.li level="0" number="2.   "><tx.p>Ordered list
item</tx.p></tx.li>
          <tx.li level="0" number="3.   "><tx.p>Ordered list
item</tx.p></tx.li>
        </tx.list>

      </wp.section>
    </wp.doc>
  </content>
</flexiondoc>

the xsl is currently

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
exclude-result-prefixes="#default fl"
xmlns:fl="http://www.outsideinsdk.com/xmlns/flexiondoc5_1";>
  <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
  <xsl:preserve-space elements="fl:tx.p"/>
  <xsl:template match="/">
    <out>
      <xsl:apply-templates/>
    </out>
  </xsl:template>

  <xsl:template match="fl:tx.p">
    <para>
      <xsl:value-of select="."/>
    </para>
  </xsl:template>
  <xsl:template match="fl:tx.li"/>
  <xsl:template
match="fl:tx.li[not(preceding-sibling::*[1][self::fl:tx.li])]">
    <xsl:apply-templates select="." mode="new-list"/>
  </xsl:template>
  <xsl:template match="fl:tx.li" mode="new-list">
    <xsl:choose>
      <xsl:when test="contains(@number,'.') or contains(@number,')')">
        <orderedlist>
          <xsl:apply-templates select="." mode="in-list"/>
        </orderedlist>
      </xsl:when>
      <xsl:otherwise>
        <itemizedlist>
          <xsl:apply-templates select="." mode="in-list"/>
        </itemizedlist>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>
  <xsl:template match="fl:tx.li" mode="in-list">
    <listitem level="{@level}" number="{@number}">
      <xsl:apply-templates select="child::*"/>
    </listitem>
    <xsl:choose>
      <xsl:when test="@level &gt;= following-sibling::*[1]/@level">
        <xsl:apply-templates
select="following-sibling::*[1][self::fl:tx.li]" mode="in-list"/>
      </xsl:when>
      <xsl:when test="@level &lt; following-sibling::*[1]/@level">
        <xsl:apply-templates
select="following-sibling::*[1][self::fl:tx.li]" mode="new-list"/>
      </xsl:when>

    </xsl:choose>
  </xsl:template>
</xsl:stylesheet>

Current output is

<?xml version="1.0" encoding="UTF-8"?>
<out>
        <para>List test</para>
        <orderedlist>
                <listitem level="0" number="1.  ">
                        <para>Ordered - list item</para>
                </listitem>
                <orderedlist>
                        <listitem level="1" number="a.  ">
                                <para>Nested list item</para>
                        </listitem>
                        <listitem level="1" number="b.  ">
                                <para>Nested list item</para>
                        </listitem>
                        <itemizedlist>
                                <listitem level="2" number="'   ">
                                        <para>Nested nested list item</para>
                                </listitem>
                                <listitem level="2" number="'   ">
                                        <para>And yet another</para>
                                </listitem>
                                <listitem level="0" number="2.  ">
                                        <para>Ordered list item</para>
                                </listitem>
                                <listitem level="0" number="3.  ">
                                        <para>Ordered list item</para>
                                </listitem>
                        </itemizedlist>
                </orderedlist>
        </orderedlist>
</out>

Desired output would mean

<?xml version="1.0" encoding="UTF-8"?>
<out>
        <para>List test</para>
        <orderedlist>
                <listitem level="0" number="1.  ">
                        <para>Ordered - list item</para>
                </listitem>
                <orderedlist>
                        <listitem level="1" number="a.  ">
                                <para>Nested list item</para>
                        </listitem>
                        <listitem level="1" number="b.  ">
                                <para>Nested list item</para>
                        </listitem>
                        <itemizedlist>
                                <listitem level="2" number="'   ">
                                        <para>Nested nested list item</para>
                                </listitem>
                                <listitem level="2" number="'   ">
                                        <para>And yet another</para>
                                </listitem>
                                     </itemizedlist>
                        </orderedlist>
                <listitem level="0" number="2.  ">
                        <para>Ordered list item</para>
                </listitem>
                <listitem level="0" number="3.  ">
                        <para>Ordered list item</para>
                </listitem>
        </orderedlist>
</out>

Current Thread