Subject: RE: xslt 2.0: grouping flat element structures to make lists
From: "Derek Revill" <derek@xxxxxxxxxxxxxxxxxx>
Date: Wed, 25 May 2005 22:23:46 +0100
|
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@xxxxxxxxx [mailto:JBryant@xxxxxxxxx]
> Sent: 25 May 2005 20:30
> To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
> Subject: Re: 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[@class='Listbegin']">
> <list>
> <xsl:apply-templates
> select="current-group()/self::par[@class='Listbegin']|current-
> group()/self::par[@class='Listitem']"/>
> </list>
> </xsl:for-each-group>
> </lists>
> </xsl:template>
>
> <xsl:template match="par[@class='Listbegin']">
> <head><xsl:value-of select="."/></head>
> </xsl:template>
>
> <xsl:template match="par[@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@xxxxxxxxxxxxxxxxxx>
> 05/25/2005 01:07 PM
> Please respond to
> xsl-list@xxxxxxxxxxxxxxxxxxxxxx
>
>
> To
> <xsl-list@xxxxxxxxxxxxxxxxxxxxxx>
> cc
>
> Subject
> 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
|