[xsl] Re: Grouping nodes by date

Subject: [xsl] Re: Grouping nodes by date
From: Dimitre Novatchev <dnovatchev@xxxxxxxxx>
Date: Wed, 10 Jul 2002 13:11:19 -0700 (PDT)
--- David Hirst <dhirst at mitre dot org> wrote:

> 
> I would like to be able to group a set of nodes based on the date
> (past
> dates and future dates)
> Is this possible (I have an extension function that returns a boolean
> if
> 
> a date is in the past).
> Currently I am selecting all the <items> arranging them in
> descindeing
> order and calling my extension function and possibly outputting data
> to
> the result tree. I was looking for a faster way to do this but have
> not
> found one to date.
> 
> so my xml looks something like
> <root>
>     <item>
>       <date>2002-07-07T12:00:00</date>
>    </item>
>     <item>
>       <date>2002-07-11T12:00:00</date>
>     </item>
>     <item>
>     ...
>     ...
>     </item>
> </root>
> 
> Thanks
> Dave Hirst
> 

Hi Dave,

Here's how to do it:

Let's have the following source xml (quite similar to yours):

<root>
  <item>
    <date>2002-07-07T19:00:00</date>
    <title>Supper</title>
  </item>
  <item>
    <date>2002-07-07T12:00:00</date>
    <title>Lunch</title>
  </item>
  <item>
    <date>2002-07-07T07:00:00</date>
    <title>Breakfast</title>
  </item>
  <item>
    <date>2002-07-11T20:00:00</date>
    <title>Supper</title>
  </item>
  <item>
    <date>2002-07-11T13:00:00</date>
    <title>Lunch</title>
  </item>
  <item>
    <date>2002-07-11T08:00:00</date>
    <title>Breakfast</title>
  </item>
</root>

The transformation bellow:

<xsl:stylesheet version="1.0" 
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>

  <xsl:output omit-xml-declaration="yes" indent="yes"/>
  
  <xsl:key name="kDate" match="item" 
           use="substring(date, 1, 10)"/>
  <xsl:template match="/">
    <xsl:for-each select="/*/item
                              [generate-id() 
                             = generate-id(key('kDate',
                                                substring(date,
                                                          1,
                                                          10)
                                               )
                                           )
                               ]">
         <xsl:sort select="date"/>
         <xsl:variable name="vthisDate" 
                       select="substring(date, 1, 10)"/>
         
         <date value="{$vthisDate}">
           
           <xsl:for-each select="/*/item
                                   [$vthisDate
                                   = substring(date, 1, 10)
                                   ]">
             <xsl:sort select="date"/>
             
             <event title="{title}" time="{substring(date, 12)}"/>
             <xsl:text>&#xA;</xsl:text>
           </xsl:for-each>
         </date>
         <xsl:text>&#xA;</xsl:text>
    </xsl:for-each>
  </xsl:template>
</xsl:stylesheet>

when applied to the source xml, produces the following result:

<date value="2002-07-07">
   <event title="Breakfast" time="07:00:00"/>

   <event title="Lunch" time="12:00:00"/>

   <event title="Supper" time="19:00:00"/>

</date>

<date value="2002-07-11">
   <event title="Breakfast" time="08:00:00"/>

   <event title="Lunch" time="13:00:00"/>

   <event title="Supper" time="20:00:00"/>

</date>


Hope this helped.

Cheers,
Dimitre Novatchev.
http://fxsl.sourceforge.net/ -- the home of FXSL




__________________________________________________
Do You Yahoo!?
Sign up for SBC Yahoo! Dial - First Month Free
http://sbc.yahoo.com

 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list


Current Thread