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

Pattern: Processing Unwrapped Repeating Groups

Subject: Pattern: Processing Unwrapped Repeating Groups
From: "W. Eliot Kimber" <eliot@xxxxxxxxxx>
Date: Wed, 30 Jan 2002 08:49:50 -0600
pattern processing
In trying to solve a problem in the style sheet I'm currently developing
I stumbled on a pattern that I hadn't seen anywhere in my reading on XSL
processing--it's probably obvious to most but it took me a while to
figure it out so I thought I would share it.

The input data consists of what I call "unwrapped repeating groups, that
is, a content model like this:

<!ELEMENT z
   (a, (b,c,d)+)
>

[I consider this style of content model to be bad form but you see it
quite a bit. My preference is to always have an intervening container
for any repeating OR or sequence groups, e.g.:

<!ELEMENT z
   (a, w+)
>
<!ELEMEMT w
   (b,d,d)
>

That is, avoid nested repeating groups. It generally makes things easier
for everybody, from authoring to processing.]

The intended presentation is as a table, e.g.:

.------------------.
| a | b1 | c1 | d1 |
|   |----|----|----|
|   | b2 | c2 | d2 |
'------------------'

The first and only "a" element starts the first row, but the 2nd..n "b"
elements start the 2nd through n rows. 

The pattern I used to solve this problem is:

<xsl:template match="z">
  <fo:table-cell starts-row="true">
    <xsl:variable name="b-elems" select="b"/>
    <xsl:attribute name="number-rows-spanned">
      <xsl:value-of select="count($b-elems)"/>
    </xsl:attribute>
    <xsl:apply-templates select="a"/>
  </fo:table-cell>
  <xsl:for-each select="b">
    <xsl:if test="position() &gt; 1">
      <fo:table-cell starts-row="true">
        <fo:block/>
      </fo:table-cell>
    </xsl:if>
    <fo:table-cell>
      <xsl:apply-templates select="."/>
    </fo:table-cell>
    <fo:table-cell>
      <xsl:apply-templates select="following::c[1]"/>
    </fo:table-cell>
    <fo:table-cell>
      <xsl:apply-templates select="following::d[1]"/>
    </fo:table-cell>
  </xsl:for-each>
</xsl:template>

I first tried doing this by generating an enclosing fo:row but found it
too combersome because you have to process the first b,c,d tupple as a
special case. Fortunately, the ability to have cells start rows
simplifies the problem. 

The key insight for me, as a novice XPath user, was the use of the
"following" axis to allow me to process the immediately following
siblings of each "b" element.

Cheers,

Eliot Kimber
ISOGEN International, LLC

 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list


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.