xsl-list
[Top] [All Lists]

RE: xslt 2.0: grouping flat element structures to make lists

2005-05-25 14:23:46
Thanks Jay. Your example gets me some way by picking the right items for the
lists (I had something like that for one of my attempts) but there are still
a couple of serious problems in my scenario that mean I can't use it:

1. The parent element of the flat structure sequence can occur in a large
number of elements e.g. section, subsection1, subsection2, p, list etc.
Since I don't know the parent (can't really code for all of them) I don't
have a nice parent node template in which to place my xsl:for-each-group
code. 

2. In your example the intermingling nodes are lost on output. I need to
preserve all of these on output, and keep them in the same relative
positions.

For these two reasons I felt forced to attach my list nesting code on the
first <par class="Listbegin"> as the trigger to start the list, then try to
get the following node sequence (i.e. all list-items up to the next
non-list-item node) and close off the list.

Am I approaching this from the right angle?

A more challenging example xml might be.

<?xml version="1.0" encoding="UTF-8"?>
<Any-element>
 <a>some text</a>
 <par class="Listbegin">Fruit</par>
 <par class="Listitem>Apple</par>
 <par class="Listitem>Orange</par>
 <par class="Listitem>Pear</par>
 <a>more text</a>
 <par class="Listbegin">Colours</par>
 <par class="Listitem>Red</par>
 <par class="Listitem>Green</par>
 <par class="Listitem>Blue</par>
 <par class="Listbegin">Shapes</par>
 <par class="Listitem>Triangle</par>
 <par class="Listitem>Circle</par>
 <par class="Listitem>Square</par>
 <a>yet more text</a>
</Any-element>

to produce

<?xml version="1.0" encoding="UTF-8"?>
<data>
 <a>some text</a>
 <list>
  <head>Fruit</head>
  <item>Apple</item>
  <item>Orange</item>
  <item>Pear</item>
 </list>
 <a>more text</a>
 <list>
  <head>Colours</head>
  <item>Red</item>
  <item>Green</item>
  <item>Blue</item>
 </list>
<list>
  <head>Shapes</head>
  <item>Triangle</item>
  <item>Circle</item>
  <item>Square</item>
 </list>
 <a>yet more text</a>
</data>  

Any more pearls of wisdom on the appreciated!

Derek

-----Original Message-----
From: JBryant(_at_)s-s-t(_dot_)com [mailto:JBryant(_at_)s-s-t(_dot_)com]
Sent: 25 May 2005 20:30
To: xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com
Subject: Re: [xsl] xslt 2.0: grouping flat element structures to make
lists

Hi, Derek,

The trick is picking just the bits you want in the list. I took your
sample lists and made a sample XML file and a stylesheet to demonstrate
one way to do it (with apply-templates).

Here's the XML file (with non-list elements intermingled with the lists):

<?xml version="1.0" encoding="UTF-8"?>
<lists>
  <par class="Listbegin">Fruit</par>
  <par class="Listitem">Apple</par>
  <par class="Listitem">Orange</par>
  <par class="Listitem">Pear</par>
  <something>thing1</something>
  <something>thing2</something>
  <par class="Listbegin">Colours</par>
  <par class="Listitem">Red</par>
  <par class="Listitem">Green</par>
  <par class="Listitem">Blue</par>
</lists>

And here's the XSL:

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

  <xsl:template match="lists">
    <lists>
      <xsl:for-each-group select="*"
group-starting-with="par[(_at_)class='Listbegin']">
        <list>
          <xsl:apply-templates
select="current-group()/self::par[(_at_)class='Listbegin']|current-
group()/self::par[(_at_)class='Listitem']"/>
        </list>
      </xsl:for-each-group>
    </lists>
  </xsl:template>

  <xsl:template match="par[(_at_)class='Listbegin']">
    <head><xsl:value-of select="."/></head>
  </xsl:template>

  <xsl:template match="par[(_at_)class='Listitem']">
    <item><xsl:value-of select="."/></item>
  </xsl:template>

</xsl:stylesheet>

And here's the resulting output:

<?xml version="1.0" encoding="UTF-8"?>
<lists>
  <list>
    <head>Fruit</head>
    <item>Apple</item>
    <item>Orange</item>
    <item>Pear</item>
  </list>
  <list>
    <head>Colours</head>
    <item>Red</item>
    <item>Green</item>
    <item>Blue</item>
  </list>
</lists>

Does that come near the mark or did I misunderstand?

(And this time I remembered to use the self axis. Thanks again to David
Carlisle.)

Jay Bryant
Bryant Communication Services
(presently consulting at Synergistic Solution Technologies)





"Derek Revill" <derek(_at_)revill(_dot_)demon(_dot_)co(_dot_)uk>
05/25/2005 01:07 PM
Please respond to
xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com


To
<xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com>
cc

Subject
[xsl] xslt 2.0: grouping flat element structures to make lists






Hello

Using XSLT 2.0 (running Saxon 8.4) I am grappling with a pretty standard
grouping issue, attempting to utilize some of XSLT v2 grouping
possibilities
but with no success (reading the W3C spec and a scan of the archive
haven't
proved helpful, MK book is on order!).

Mid flow I have:

..
..
<par class="Listbegin">Fruit</par>
<par class="Listitem>Apple</par>
<par class="Listitem>Orange</par>
<par class="Listitem>Pear</par>
<par class="Listbegin">Colours</par>
<par class="Listitem>Red</par>
<par class="Listitem>Green</par>
<par class="Listitem>Blue</par>
..
..

I just need to output

..
..
<list>
                 <head>Fruit</head>
                 <item>Apple</item>
                 <item>Orange</item>
                 <item>Pear</item>
</list>
<list>
                 <head>Colours</head>
                 <item>Red</item>
                 <item>Green</item>
                 <item>Blue</item>
</list>

Note: I'm midway through processing any section when I encounter the <par
class="Listbegin">. The signal that a list has ended can be any
following-sibling that isn't <par class="Listitem>..</par> or the end of
the
parent element I'm in. Of course, lists don't always come in pairs like
above.

Should I try to match on the <par class="Listbegin"> then scoop-up all
relevant following nodes, which was my strategy up to now? Haven't been
able
to find a way to scoop-up only the following nodes that are relevant.

Any advice gratefully received. Numerous attempts using for-each-group and
various group-by strategies have been fruitless, probably I just haven't
quite grasped it!

Thanks

Derek Revill




--~------------------------------------------------------------------
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>
--~--


--~------------------------------------------------------------------
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>
--~--