Re: [xsl] XPath question

Subject: Re: [xsl] XPath question
From: Evan Lenz <evan@xxxxxxxxxxxx>
Date: Thu, 2 May 2002 20:56:47 -0700
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


Current Thread