Re: [xsl] Break on first - question

Subject: Re: [xsl] Break on first - question
From: Jeni Tennison <jeni@xxxxxxxxxxxxxxxx>
Date: Mon, 6 Jan 2003 14:14:59 +0000
Hi,

> Note: Since this is my calendar, I can write the startDate and endDate as
> xsl:date (<startDate>2003-01-25</startDate>), and in fact would prefer to.

If you did, you would currently have to extract the year, month and
day using substring() or similar; that's probably not a particular
hardship, in fact with the grouping that you want to do it's
marginally easier, so I'm going to assume that you've done this.

> I have many EVENT records and need to sort them (I can do the sort
> just fine) by date and title, and then produce HTML that breaks on
> each new month (or year) so I can insert some formatting etc.. So
> it's a grouping issue. How in the world do I do it? Whatever I try
> gives me some success (=complete failure) but I can't get every new
> month to behave itself.

Using the Muenchian Method, create a key that indexes your <EVENT>
elements by the month (and year) of their <eventDate>:

<xsl:key name="events" match="EVENT"
         use="substring(venue/eventDate/startDate, 1, 7)" />

Now you can get all the events that start in January 2003 with the
function call:

  key('events', '2003-01')

So given a particular event you could create a list of all the events
that occurred in the same month as that event, sorted by their date,
using:

<xsl:template match="EVENT" mode="month-group">
  <xsl:variable name="month"
    select="substring(venue/eventDate/startDate, 1, 7)" />
  <h3><xsl:value-of select="$month" /></h3>
  <xsl:apply-templates select="key('events', $month)"
                       mode="details">
    <xsl:sort select="venue/eventDate/startDate" />
  </xsl:apply-templates>
</xsl:template>

(Assuming that you have a template matching EVENT elements in details
mode that gives the details about an EVENT.)

You only want to process the first EVENT of each month using the
month-group template above, so you have to apply templates to only
that set of elements. This is where the Muenchian trick comes in. Use:

  <xsl:apply-templates mode="month-group"
    select="EVENT[generate-id() =
                  generate-id(
                    key('events',
                        substring(venue/eventDate/startDate, 1, 7))[1])]">
    <xsl:sort select="venue/eventDate/startDate" />
  </xsl:apply-templates>

This selects the first listed EVENT for each month, sorts them in date
order, and applies templates to them in month-group mode.
                        
Cheers,

Jeni

---
Jeni Tennison
http://www.jenitennison.com/


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


Current Thread