On 17/03/2008, Ian Proudfoot <ian(_dot_)proudfoot(_at_)itp-x(_dot_)co(_dot_)uk>
wrote:
I have a blind spot when it comes to grouping flat XML structure using XSLT
1.0.
My source XML structure is typically as follows (simplified for clarity):
<section>
<title/>
<warning/>
<warning/>
<para/>
<warning/>
<warning/>
<para/>
<para/>
</section>
I would like to group adjacent <warning> elements to give this structure:
<section>
<title/>
<w-group>
<warning/>
<warning/>
</w-group>
<para/>
<w-group>
<warning/>
<warning/>
</w-group>
<para/>
<para/>
</section>
I've tried using Muenchian Grouping, but I'm going wrong somewhere. I
started by trying to identify the start of each group using <xsl:template
match="warning[(preceding-sibling::*[1])[not(self::warning)]]">... As a
starting point is this correct, it does seem to capture the first warning in
each group? After that I cannot grab the following <warning> sibling
elements correctly.
You can use the "sibling-recursion" template (also known as the
"modified identity tempate") which walks the sibling axis one node at
time:
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:apply-templates select="node()[1]"/>
</xsl:copy>
<xsl:apply-templates select="following-sibling::node()[1]"/>
</xsl:template>
Then have a specific template to process <warning> elements - output
the container element and then process the warning using a special
moded template to differentiate it from this template. The next
non-warning element is processed after the container element.
<xsl:template match="warning">
<w-group>
<xsl:apply-templates select="." mode="copy"/>
</w-group>
<xsl:apply-templates
select="(following-sibling::*[not(self::warning)])[1]"/>
</xsl:template>
This is the template that effectively groups the warnings - it copies
the current warning (or probably processes it in your real transform)
and then processes the next node as long as it's a warning:
<xsl:template match="warning" mode="copy">
<xsl:copy-of select="."/>
<xsl:apply-templates
select="following-sibling::*[1][self::warning]" mode="copy"/>
</xsl:template>
cheers
--
Andrew Welch
http://andrewjwelch.com
Kernow: http://kernowforsaxon.sf.net/
--~------------------------------------------------------------------
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>
--~--