This is the mail archive of the
xsl-list@mulberrytech.com
mailing list .
Re: XPath question
- From: Evan Lenz <evan at evanlenz dot net>
- To: xsl-list at lists dot mulberrytech dot com
- Date: Thu, 2 May 2002 20:56:47 -0700
- Subject: Re: [xsl] XPath question
- Reply-to: xsl-list at lists dot mulberrytech dot com
This is an example of the classic grouping problem.
Here's an XSLT 1.0 solution:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:template match="data">
<data>
<series>
<xsl:for-each
select="series/event[not(@time=preceding::event/@time)]">
<record time="{@time}">
<xsl:for-each
select="//data/series/event[@time=current()/@time]">
<sample ID="{../@ID}">
<xsl:value-of select="."/>
</sample>
</xsl:for-each>
</record>
</xsl:for-each>
</series>
</data>
</xsl:template>
<xsl:template match="@*|*">
<xsl:copy>
<xsl:apply-templates select="@*|*"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Here's an XSLT 2.0 solution (tested on Saxon 7.1):
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:template match="data">
<data>
<series>
<xsl:for-each-group select="series/event" group-by="@time">
<record time="{@time}">
<xsl:for-each select="current-group()">
<sample ID="{../@ID}">
<xsl:value-of select="."/>
</sample>
</xsl:for-each>
</record>
</xsl:for-each-group>
</series>
</data>
</xsl:template>
<xsl:template match="@*|*">
<xsl:copy>
<xsl:apply-templates select="@*|*"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
For an explanation of this new XSLT 2.0 feature (as well as a few others),
see the second page of my article[1] on XML.com.
Hope this helps,
Evan
[1] http://www.xml.com/pub/a/2002/04/10/xslt2.html?page=2
On Thursday, May 2, 2002, at 07:45 PM, Joseph Brightly wrote:
> I'm trying to perform an xml->xml transform and I can't seem
> to be able to make it work. The following is the xml, with
> extraneous stuff taken out.
>
> I need to go from this:
>
> <session startDate="03/23/2002" startTime="11:20:05">
> <data>
> <series ID="100">
> <event time="11:20:05">65.05</event>
> <event time="11:21:05">65.23</event>
> <event time="11:22:05">67.46</event>
> </series>
> <series ID="200">
> <event time="11:20:05">40.15</event>
> <event time="11:21:05">40.17</event>
> <event time="11:22:05">40.56</event>
> </series>
>
> 1 - N of these <series> elements...
>
> </data>
> </Session>
>
> To this:
>
> <session startDate="03/23/2002" startTime="11:20:05">
> <data>
> <series>
> <record time="11:20:05">
> <sample ID="100">65.05</sample>
> <sample ID="200">40.15</sample>
> </record>
> <record time="11:21:05">
> <sample ID="100">65.23</sample>
> <sample ID="200">40.17</sample>
> </record>
> <record time="11:22:05">
> <sample ID="100">67.46</sample>
> <sample ID="200">40.56</sample>
> </record>
>
> Etc...
>
> </series>
> </data>
> </session>
>
> This is something like a table join in sql, and I can't find a way
> to accomplish it.
>
> Any help would be greatly appreciated.
>
>
> XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
>
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list