Subject: Re: how to update a variable (grouping question)
From: andrew welch <andrew.j.welch@xxxxxxxxx>
Date: Tue, 9 Aug 2005 09:58:08 +0100
|
> I am trying to retrieve data from a table structure (xml table) where
> after every few rows a special row appears which contains a piece of
> data which is relevant to rows appearing immidiatley after it (i.e.
> its next few siblings). I am having hard time figuring out how to
> achieve this without a dynamically assigned variable in XSL.
>
> Test data looks like this:
>
> <schedule>
> <row type="header">
> <col>January</col>
> <col>Opponent</col>
> </row>
> <row type="data">
> <col>10 at 6pm</col>
> <col>Dallas</col>
> </row>
> <row type="data">
> <col>21 at 8pm</col>
> <col>New York</col>
> </row>
> <row type="data">
> <col>31 at 8pm</col>
> <col>Chicago</col>
> </row>
> <row type="header">
> <col>March</col>
> <col>Opponent</col>
> </row>
> <row type="data">
> <col>16 at 9pm</col>
> <col>Houston</col>
> </row>
> <row type="data">
> <col>31 at 7pm</col>
> <col>Sacramento</col>
> </row>
> </schedule>
>
> and the desired output is:
> <schedule>
> <date>January 10 at 6pm</date>
> <date>January 21 at 8pm</date>
> <date>January 31 at 8pm</date>
> <date>March 16 at 9pm</date>
> <date>March 31 at 7pm</date>
> </schedule>
The technique here is to apply-templates to each row with type =
'header', then apply-templates to all following-siblings whose nearest
preceding-sibling row type = 'header' is that current row.
It's called positional grouping and is explained well at jeni's site
http://www.jenitennison.com/xslt/index.html under grouping.
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<schedule>
<xsl:apply-templates select="/sechedule/row[@type = 'header']"/>
</schedule>
</xsl:template>
<xsl:template match="row[@type = 'header']">
<xsl:apply-templates select="following-sibling::row[@type =
'data'][generate-id(preceding-sibling::row[@type = 'header'][1]) =
generate-id(current())]">
<xsl:with-param name="month" select="col[1]"/>
</xsl:apply-templates>
</xsl:template>
<xsl:template match="row[@type = 'data']">
<xsl:param name="month" select="'error'"/>
<data><xsl:value-of select="concat($month, ' ', col[1])"/></data>
</xsl:template>
</xsl:stylesheet>
cheers
andrew
|