xsl-list
[Top] [All Lists]

RE: [xsl] For-each-group groups elements before the first group-starting-with element

2010-05-11 03:06:21
group-starting-with allocates every selected item to one group; it starts a
new group for the first item and for every item that matches the pattern.

This means it is often necessary to treat the first group specially; in this
case the logic might be 

     <xsl:for-each-group select = "*" group-starting-with = "h1" >
         <xsl:apply-templates select="." mode="group"/>
     </xsl:for-each-group>

     <xsl:template match="h1" mode="group">
         <section>
            <xsl:apply-templates select="current-group()"/>
         </section>
     </xsl:template>

     <xsl:template match="*" mode="group">
        <xsl:apply-templates select="current-group()"/>
     </xsl:template>

Regards,

Michael Kay
http://www.saxonica.com/
http://twitter.com/michaelhkay 

-----Original Message-----
From: Peter Desjardins 
[mailto:peter(_dot_)desjardins(_dot_)us(_at_)gmail(_dot_)com] 
Sent: 11 May 2010 03:50
To: xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com
Subject: [xsl] For-each-group groups elements before the 
first group-starting-with element

Hi. I'm new to XSLT and I'm trying to write a 2.0 stylesheet 
to wrap HTML elements in DocBook <section> elements.  I'm 
finding that <xsl:for-each-group> wraps elements in a 
<section> even when they are not preceded by the element I 
name in the group-starting-with attribute.

For example, I'm converting the HTML <body> element to a 
DocBook <chapter> element. If the HTML includes <p> elements 
before the first <h1> element, they should become <para> 
elements that are children of the <chapter> element. I name 
<h1> in the group-starting-with attribute but my output 
includes a <section> element around the first <para> elements.

My processor is Saxon HE 9.2.1.1. I've pasted the source, 
stylesheet, and output below. Am I using the for-each-group 
element incorrectly? I figured out a way to work around this 
problem by including a predicate [preceding-sibling::h1] in 
the select attribute for it.  However, this won't work when I 
need to wrap <h2> and <h3> sections later in the document.

Has anyone dealt with this situation before?  Thanks for your help.

Peter

***********  Source  ***********

<?xml version="1.0" encoding="UTF-8"?>
<html>
    <body>
        <p>Acorn</p>
        <p>Bee</p>
        <h1>1 Heading One</h1>
        <p>Caterpillar</p>
        <p>Dragonfly</p>
    </body>
</html>

***********  Stylesheet  ***********

<xsl:template match = "body" >
    <xsl:for-each-group select = "*" group-starting-with = "h1" >
        <xsl:element name="section">
            <xsl:apply-templates select="current-group()"/>
        </xsl:element>
    </xsl:for-each-group>
</xsl:template>

***********  Output  ***********

<?xml version="1.0" encoding="UTF-8"?>
<book>
   <chapter>
      <section>
         <para>Acorn</para>
         <para>Bee</para>
      </section>
      <section>
         <title>1 Heading One</title>
         <para>Caterpillar</para>
         <para>Dragonfly</para>
      </section>
   </chapter>
</book>

--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: 
<mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--



--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--