Re: [xsl] XSLT grouping without Muenchen Method

Subject: Re: [xsl] XSLT grouping without Muenchen Method
From: "cking" <cking@xxxxxxxxxx>
Date: Mon, 30 Aug 2004 20:47:46 +0200
Hi Ismael,

Here's a solution in two passes:

--- pass1.xsl ---
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>
 <xsl:output method="xml" indent="yes"/>
 <xsl:template match="/root">
  <root>
   <xsl:apply-templates select="object"/>
  </root>
 </xsl:template>
 <xsl:template match="object">
  <object name="{@name}" instance="{concat('Instance', instance/@number)}">
   <xsl:attribute name="interval">
    <xsl:value-of select="substring-before(instance/sample/@date_time, ':')"/>
    <xsl:call-template name="calculate-interval">
     <xsl:with-param name="time" select="substring-after(instance/sample/@date_time, ':')"/>
    </xsl:call-template>
   </xsl:attribute>
  </object>
 </xsl:template>
 <xsl:template name="calculate-interval">
  <xsl:param name="time"/>
  <xsl:variable name="hour" select="number(substring-before($time, ':'))"/>
  <xsl:choose>
   <xsl:when test="$hour &lt; 15">:00:00</xsl:when>
   <xsl:when test="$hour &lt; 30">:15:00</xsl:when>
   <xsl:when test="$hour &lt; 45">:30:00</xsl:when>
   <xsl:otherwise>:45:00</xsl:otherwise>
  </xsl:choose>
 </xsl:template>
</xsl:stylesheet>

This will produce this intermediate xml file:
<root>
   <object name="object1" instance="Instance0" interval="2004-08-30 15:00:00"/>
   <object name="object2" instance="Instance0" interval="2004-08-30 15:30:00"/>
   <object name="object3" instance="Instance0" interval="2004-08-30 15:00:00"/>
   <object name="object4" instance="Instance1" interval="2004-08-30 15:00:00"/>
   <object name="object5" instance="Instance1" interval="2004-08-30 15:30:00"/>
   <object name="object6" instance="Instance1" interval="2004-08-30 15:00:00"/>
</root>

Which then you can transform in a second pass:

--- pass2.xsl ---
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>
 <xsl:output method="text"/>
 <xsl:template match="/root">
  <xsl:apply-templates select="object">
   <xsl:sort select="@interval"/>
   <xsl:sort select="@instance"/>
  </xsl:apply-templates>
 </xsl:template>
 <xsl:template match="object">
  <xsl:variable name="interval" select="@interval"/>
  <xsl:variable name="instance" select="@instance"/>
  <xsl:if test="not(preceding-sibling::object[@interval=$interval and @instance=$instance])">
   <!-- first of group -->
   <xsl:apply-templates select="self::object | following-sibling::object[@interval=$interval and @instance=$instance]"
mode="write"/>
   <xsl:value-of select="@instance"/>
   <xsl:text>;</xsl:text>
   <xsl:value-of select="@interval"/>
   <xsl:text>&#xA;</xsl:text>
  </xsl:if>
 </xsl:template>
 <xsl:template match="object" mode="write">
  <xsl:value-of select="@name"/>
  <xsl:text>;</xsl:text>
 </xsl:template>
</xsl:stylesheet>

Which will give you this text file:
object1;object3;Instance0;2004-08-30 15:00:00
object4;object6;Instance1;2004-08-30 15:00:00
object2;Instance0;2004-08-30 15:30:00
object5;Instance1;2004-08-30 15:30:00

I'm not familiar with XT, does it support node-sets?
If so, you could use that to do it in one pass only.

HTH,

Best regards
Anton Triest


Ismael Cams wrote:
>

> Hello all,
>
> I hope somebody can help me with the following problem as I got stuck with
> it. I have following structure:
>
> <root>
>     <object name="object1">
>           <instance number="0">
>                  <sample date_time="2004-08-30 15:06:20"/>
>           </instance>
>     </object>
>     <object name="object2">
>           <instance number="0">
>                  <sample date_time="2004-08-30 15:30:20"/>
>           </instance>
>     </object>
>     <object name="object3">
>           <instance number="0">
>                  <sample date_time="2004-08-30 15:14:20"/>
>           </instance>
>     </object>
>     <object name="object4">
>           <instance number="1">
>                  <sample date_time="2004-08-30 15:06:20"/>
>           </instance>
>     </object>
>      <object name="object5">
>           <instance number="1">
>                  <sample date_time="2004-08-30 15:30:20"/>
>           </instance>
>     </object>
>      <object name="object6">
>           <instance number="1">
>                  <sample date_time="2004-08-30 15:14:20"/>
>           </instance>
>     </object>
> </root>
>
> In the result file I need a grouped structure. As the application for which
> I have to foresee the stylesheet uses the XT processor of James Clark I can
> not use the xsl:key function.
>
> The output format I need:
>
> object1,object3;Instance0;2004-08-30 15:00:00
> object4,object6;Instance1;2004-08-30 15:00:00
> object2;Instance0;2004-08-30 15:30:00
> object5;Instance1;2004-08-30 15:30:00
>
> So there is a grouping pro instance and a grouping pro timeinterval. One
> hour is divided into four time intervals:
>
> 00 - 15 -> Interval 1
> 15 - 30 -> Interval 2
> 30 - 45 -> Interval 3
> 45 - 60 -> Interval 4
>
> The grouping pro instance is straight forward, but the grouping with the
> time intervals has caused me already a lot of headaches.
>
> I hope somebody can provide me with a solution for this problem.
>
> Thanks in advance.
>
> Kind regards,
> ismael

Current Thread