[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message]

XSLT 2.0 Grouping in XSLT 1.0 (was TEI > XML)

Subject: XSLT 2.0 Grouping in XSLT 1.0 (was TEI > XML)
From: Daniel O'Donnell <daniel.odonnell@xxxxxxxx>
Date: Wed, 13 Apr 2005 00:05:01 -0600
xslt match newline
Thanks to Jim and Mark for the suggestions for solving my problem... unfortunately, neither produce valid XHTML: the intervening bits of paragraph are still untagged.

That is to say, for the valid TEI/XML input:

<p>Text
 <quote>
  <p>quotation text</p>
 </quote>
 end text.</p>

The XHTML output (invalid) is

<p>text
 <blockquote>
  <p>quotation text</p>
 </blockquote>
 end text.</p>

not (valid):

 <p>text</p>
  <blockquote>
   <p>quotation text</p>
  </blockquote>
 <p>end text</p>


In the meantime, I've done a bit more research, and have discovered the solution in XSLT 2.0 (it's a canonical example): <http://www.w3.org/TR/xslt20/#d5e20377> "Grouping Alternating Sequences of Elements".


So to refine my question:

Is there a way of reproducing the results one gets in XSLT 2.0 (using the various grouping elements and attributes) in XSLT 1.0 (where these commands are not available).

Here is the example, desired output, and xslt 2.0 from the w3c:

Source XML document:

<p>Do <em>not</em>:
    <ul>
    <li>talk,</li>
    <li>eat, or</li>
    <li>use your mobile telephone</li>
    </ul>
    while you are in the cinema.</p>

Desired output:

<p>Do <em>not</em>:*</p>*
    <ul>
    <li>talk,</li>
    <li>eat, or</li>
    <li>use your mobile telephone</li>
    </ul>
    *<p>*while you are in the cinema.</p>

Solution:

This requires creating a p element around the maximal sequence of sibling nodes that does not include a ul or ol element.

This can be done by using group-adjacent, with a grouping key that is true if the element is a ul or ol element, and false otherwise:

<xsl:template match="p">
<xsl:for-each-group select="node()" group-adjacent="self::ul or self::ol">
<xsl:choose>
<xsl:when test="current-grouping-key()">
<xsl:copy-of select="current-group()"/> </xsl:when>
<xsl:otherwise>
<p>
<xsl:copy-of select="current-group()"/>
</p>
</xsl:otherwise> </xsl:choose>
</xsl:for-each-group>
</xsl:template>



Adapted to the specific circumstance at hand, and applied to a test file (http://people.uleth.ca/~caedmon/lorem.xml), the following XSLT 2.0 produces valid results (http://people.uleth.ca/~caedmon/lorem.htm):


<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                version="2.0">

<xsl:output method="xml"/>

  <xsl:variable name="newline">
    <xsl:text>
    </xsl:text>
  </xsl:variable>

  <xsl:template match="/">
    <html>
      <head>
        <title>Quotes test</title>
      </head>
      <body>
        <xsl:apply-templates select="//body"/>
      </body>
    </html>
  </xsl:template>

  <xsl:template match="body">
    <xsl:apply-templates/>
  </xsl:template>

<xsl:template match="teiHeader//*"/>

  <xsl:template match="quote[p]">
    <blockquote>
      <xsl:apply-templates/>
    </blockquote><xsl:value-of select="$newline"/>
  </xsl:template>

  <xsl:template match="table">
    <table><xsl:value-of select="$newline"/>
      <xsl:apply-templates/>
    </table><xsl:value-of select="$newline"/>
  </xsl:template>

  <xsl:template match="row">
    <tr><xsl:value-of select="$newline"/>
      <xsl:apply-templates/><xsl:value-of select="$newline"/>
    </tr><xsl:value-of select="$newline"/>
  </xsl:template>

  <xsl:template match="cell">
    <td>
      <xsl:apply-templates/>
    </td>
  </xsl:template>

  <xsl:template match="list">
    <xsl:choose>
      <xsl:when test="@rend='ordered'">
        <ol><xsl:value-of select="$newline"/>
          <xsl:apply-templates/>
        </ol><xsl:value-of select="$newline"/>
      </xsl:when>
      <xsl:otherwise>
        <ul><xsl:value-of select="$newline"/>
          <xsl:apply-templates/>
        </ul><xsl:value-of select="$newline"/>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>

  <xsl:template match="item">
    <li>
      <xsl:apply-templates/>
    </li><xsl:value-of select="$newline"/>
  </xsl:template>

  <xsl:template match="p">
    <xsl:for-each-group select="node()"
      group-adjacent="self::quote[p] or self::table or self::list">
      <xsl:choose>
        <xsl:when test="current-grouping-key()">
          <xsl:apply-templates select="current-group()"/>
        </xsl:when>
        <xsl:otherwise>
          <p>
            <xsl:copy-of select="current-group()"/>
          </p>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:for-each-group>
  </xsl:template>

</xsl:stylesheet>


So the question is, how (can?) can this be done in XSLT 1.0?


Thanks again.
-dan

--
Daniel Paul O'Donnell, PhD
Associate Professor of English
University of Lethbridge
Lethbridge AB T1K 3M4
Tel. (403) 329-2377
Fax. (403) 382-7191
E-mail <daniel.odonnell@xxxxxxxx>
Home Page <http://people.uleth.ca/~daniel.odonnell/>
The Digital Medievalist Project: <http://www.digitalmedievalist.org/>

Current Thread

PURCHASE STYLUS STUDIO ONLINE TODAY!

Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced!

Buy Stylus Studio Now

Download The World's Best XML IDE!

Accelerate XML development with our award-winning XML IDE - Download a free trial today!

Don't miss another message! Subscribe to this list today.
Email
First Name
Last Name
Company
Subscribe in XML format
RSS 2.0
Atom 0.3
Site Map | Privacy Policy | Terms of Use | Trademarks
Free Stylus Studio XML Training:
W3C Member
Stylus Studio® and DataDirect XQuery ™are products from DataDirect Technologies, is a registered trademark of Progress Software Corporation, in the U.S. and other countries. © 2004-2013 All Rights Reserved.