|
Subject: Re: [xsl] Grouping simple flat structure From: "Andrew Welch" <andrew.j.welch@xxxxxxxxx> Date: Mon, 17 Mar 2008 13:01:00 +0000 |
On 17/03/2008, Ian Proudfoot <ian.proudfoot@xxxxxxxxxxx> 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/
| Current Thread |
|---|
|
| <- Previous | Index | Next -> |
|---|---|---|
| RE: [xsl] Grouping simple flat stru, Michael Kay | Thread | RE: [xsl] Grouping simple flat stru, Ian Proudfoot |
| RE: [xsl] Grouping simple flat stru, Michael Kay | Date | RE: [xsl] Grouping simple flat stru, Ian Proudfoot |
| Month |