Re: [xsl] Flat to Structured: Handling List Items with Subordinate Paragraphs

Subject: Re: [xsl] Flat to Structured: Handling List Items with Subordinate Paragraphs
From: "G. Ken Holman" <gkholman@xxxxxxxxxxxxxxxxxxxx>
Date: Tue, 26 May 2009 17:10:36 -0400
At 2009-05-26 15:51 -0500, Eliot Kimber wrote:
I don't think it's quite as easy as my sample data suggested.

Once I have a group of contained things, there's no guarantee that the
first-level containers are homogenous.

Then do a group-starting-with whenever the kind of container changes.


For example, I could have an ordered list followed by an unordered list,
which would give a group like:

<p type="li" container="ol" level="1">
<p type="p" container="li" level="2">
<p type="li" container="ol" level="1">
<p type="p" container="li" level="2">
<p type="li" container="ul" level="1">
<p type="p" container="li" level="2">

Where the result should be:

<ol>
  <li>
    <p>
  </li>
  <li>
    <p>
  <li>
</ol>
<ul>
  <li>
   <p>
  <li>
</ul>

I don't see a way to get that result using group-starting-with on the group
members.

By comparing the type of the immediately preceding level 1 container.


But I think that sibling recursion might be more tractable on the group
members since I don't have to worry about excluding elements that don't have
a container at all.

Sure ... but I think doing this declaratively is better than procedurally ... all one has to do is figure out what is distinctive.


I hope this helps.

. . . . . . . . . . . . Ken

T:\ftemp>type eliot.xml
<doc>
<p type="para" level="1">Para 1</p>
<p container="ol" type="li" level="1">ol item 1</p>
<p container="li" type="p" level="2">Para w/in li</p>
<p container="ol" type="li" level="1">ol item 2</p>
<p container="li" type="p" level="2">Para w/in li</p>
<p container="ul" type="li" level="1">ul item 1</p>
<p container="li" type="p" level="2">Para w/in li</p>
<p type="para" level="1">Para 2</p>
</doc>
T:\ftemp>xslt2 eliot.xml eliot.xsl
<?xml version="1.0" encoding="UTF-8"?>
<para>Para 1</para>
<ol>
   <li>ol item 1<p>Para w/in li</p>
   </li>
   <li>ol item 2<p>Para w/in li</p>
   </li>
</ol>
<ul>
   <li>ul item 1<p>Para w/in li</p>
   </li>
</ul>
<para>Para 2</para>
T:\ftemp>type eliot.xsl
<?xml version="1.0" encoding="US-ASCII"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
                version="2.0">

<xsl:output indent="yes"/>

<xsl:template match="doc">
  <!--determine containers by the members being adjacent-->
  <xsl:for-each-group select="*"
                      group-adjacent="boolean(@container)">
    <xsl:choose>
      <xsl:when test="@container">
        <!--at a sequence of container constructs-->
        <!--start whenever the kind of container changes-->
        <xsl:for-each-group select="current-group()"
                            group-starting-with="*[@level='1' and
             not(@container=preceding-sibling::*[@level='1'][1]/@container)]">
          <!--create the necessary kind of container-->
          <xsl:element name="{@container}">
            <!--populate the container-->
            <xsl:for-each-group select="current-group()"
                                group-starting-with="*[@type='li']">
              <li>
                <!--the first member of the group is processed raw-->
                <xsl:apply-templates select="node()"/>
                <!--other members of the group are nested inside-->
                <xsl:apply-templates select="current-group()[position()>1]"/>
              </li>
            </xsl:for-each-group>
          </xsl:element>
        </xsl:for-each-group>
      </xsl:when>
      <xsl:otherwise>
        <!--not at a container; just constitute the elements-->
        <xsl:apply-templates select="current-group()"/>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:for-each-group>
</xsl:template>

<xsl:template match="*">
  <xsl:element name="{@type}">
    <xsl:apply-templates/>
  </xsl:element>
</xsl:template>

</xsl:stylesheet>

T:\ftemp>

--
XSLT/XSL-FO/XQuery hands-on training - Los Angeles, USA 2009-06-08
Crane Softwrights Ltd.          http://www.CraneSoftwrights.com/s/
Training tools: Comprehensive interactive XSLT/XPath 1.0/2.0 video
Video lesson:    http://www.youtube.com/watch?v=PrNjJCh7Ppg&fmt=18
Video overview:  http://www.youtube.com/watch?v=VTiodiij6gE&fmt=18
G. Ken Holman                 mailto:gkholman@xxxxxxxxxxxxxxxxxxxx
Male Cancer Awareness Nov'07  http://www.CraneSoftwrights.com/s/bc
Legal business disclaimers:  http://www.CraneSoftwrights.com/legal

Current Thread