[XSL-LIST Mailing List Archive Home]
[By Thread]
[By Date]
Re: [xsl] Positional grouping with exceptions
Subject: Re: [xsl] Positional grouping with exceptions
From: "Andrew Welch" <andrew.j.welch@xxxxxxxxx>
Date: Wed, 20 Dec 2006 15:28:15 +0000
|
On 12/20/06, Fredrik Geers <fredrik@xxxxxxxxxx> wrote:
I have the following xml:
<book>
<header>title</header>
<a>text</a>
<a>text</a>
<otherelement>title</otherelement>
<a>text</a>
<a>text</a>
<a/>
<a>text</a>
</book>
I want to group each block of consecutive <a> tags inside an <al> tag,
like this:
<book>
<header>title</header>
<al>
<a>text</a>
<a>text</a>
</al>
<otherelement>title</otherelement>
<al>
<a>text</a>
<a>text</a>
</al>
<al>
<a>text</a>
</al>
</book>
And like you can see in the example, I want to start a new <al> block
when an empty <a> tag is found. That's the hard part. Well, the other
part also isn't that easy...
I think you need a modified identity transform for this one. The
following stylesheet walks the tree along the following-sibling axis,
allowing you to group <a>'s with text as you come across them:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="node()">
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:apply-templates select="node()[1]"/>
</xsl:copy>
<xsl:apply-templates select="following-sibling::*[1]"/>
</xsl:template>
<xsl:template match="a[text()]">
<al>
<xsl:apply-templates select="." mode="fill"/>
</al>
<xsl:apply-templates select="following-sibling::*[not(self::a[text()])][1]"/>
</xsl:template>
<xsl:template match="a[text()]" mode="fill">
<xsl:copy-of select="."/>
<xsl:apply-templates
select="following-sibling::*[1][self::a[text()]]" mode="fill"/>
</xsl:template>
</xsl:stylesheet>
The output generated is:
<book>
<header>title</header>
<al>
<a>text</a>
<a>text</a>
</al>
<otherelement>title</otherelement>
<al>
<a>text</a>
<a>text</a>
</al>
<a/>
<al>
<a>text</a>
</al>
</book>
Notice the <a/> which wasnt present in your example - easy to suppress
if that really is the case.
By the way, Saxon 8.8 is available now.
cheers
andrew
|