[XSL-LIST Mailing List Archive Home] [By Thread] [By Date]

[xsl] Processing and sorting non-military time


Subject: [xsl] Processing and sorting non-military time
From: "Andrew Fraser" <scenedance@xxxxxxxxx>
Date: Thu, 16 Aug 2007 23:57:33 -0500

Hello there.  Thank you for maintaining such a helpful xslt resource.

I'm a complete beginner, but have managed work with xsl through
examples and other q&a's.

I'm working with an xml file of events and need to list all of the
events by day, in order of start time.  I've managed to group the
events by day and list by start time, but since the time format is
non-military I'm having trouble dealing with correctly sorting events
that occur from 12 noon to 12:59.

Here is a sample from the xml:

<events>
<event>
	<title>First event</title>
	<occurrences>
		<occurrence>
			<start>08/10/2007 12:30 PM</start>
			<end>08/10/2007 02:00 PM</end>
		</occurrence>
	</occurrences>
</event>
<event>
	<title>Second event</title>
	<occurrences>
		<occurrence>
			<start>08/10/2007 08:30 PM</start>
			<end>08/10/2007 09:00 PM</end>
		</occurrence>
	</occurrences>
</event>
<event>
	<title>Third event</title>
	<occurrences>
		<occurrence>
			<start>08/10/2007 10:30 AM</start>
			<end>08/10/2007 01:00 PM</end>
		</occurrence>
	</occurrences>
</event>
</events>

So I set up my keys for grouping by day, and then I'm using the
following code to reformat a sortable string from the start date/time:

<xsl:sort order="ascending"
select="concat(substring(occurrences/occurrence/start,18,2),substring(occurrences/occurrence/start,12,2),substring(occurrences/occurrence/start,15,2))"
/>

It will list the AM events first, then look to ascending hour number,
then to minute.  This would work great if the hours were in military
time, but instead it will put early afternoon events from 12 to 1
after late night events, since they are both PM and 12 comes last.

I understand why this does this, and ideally I'd like to reprocess the
start string either into military time, or replace the hour if it's
"12" in pm strings to "00" for sorting, then change it back to "12"
for output.

I've read quite a few examples on other techniques where this might
apply, but I'm too new to XSLT to understand where it would go in the
code.

Here is a bigger excerpt of my code.  It's doing exactly what I want
outside of the 12 p.m. hook explained above:


<?xml version="1.0" encoding="ISO-8859-1"?><!-- DWXMLSource="Events.xml" -->
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>

<xsl:key name="events-by-date" match="event"
use="substring(occurrences/occurrence/start,1,10)" />
<xsl:template match="events">

<xsl:for-each select="event[count(. | key('events-by-date',
substring(occurrences/occurrence/start,1,10))[1]) = 1]">
	

	<xsl:sort select="substring(occurrences/occurrence/start,1,10)" />
		<!-- add date header hopefully -->
		<xsl:value-of select="substring(occurrences/occurrence/start,1,10)" />
		<xsl:value-of select="$newline"/>
		<!-- end date header -->
	
		<!-- loop through events for that date -->
		<xsl:for-each select="key('events-by-date',
substring(occurrences/occurrence/start,1,10))">

		<!-- sort earliest events first -->
		<xsl:sort order="ascending"
select="concat(substring(occurrences/occurrence/start,18,2),substring(occurrences/occurrence/start,12,2),substring(occurrences/occurrence/start,15,2))"
/>

		<xsl:value-of select="title"/><xsl:text>, </xsl:text>
		<xsl:value-of select="$date"/>
		<xsl:for-each select="occurrences/occurrence">
			<!-- format date and time for output -->
                        <xsl:call-template name="occurrence">
                            <xsl:with-param name="start" select="start" />
                            <xsl:with-param name="end" select="end" />
                        </xsl:call-template>
		</xsl:for-each><xsl:text>. </xsl:text>
		<xsl:value-of select="$newline"/>
	</xsl:for-each>

		
</xsl:for-each>
</xsl:template><!-- End of main template -->

<xsl:template name="occurrence">
<!-- Code that formats date and time for output -->
</xsl:template>

</xsl:stylesheet>

Thank you in advance for any insight you can provide.  I'm guessing I
need to process the date/time before I put it through the rounds, but
like I said I'm too new to understand where in the workflow this needs
to happen.


Current Thread
Keywords