Sorting Dates in XSL






2.90/5 (10 votes)
Jun 3, 2003
2 min read

87345
Sorting dates in XSL
Introduction
This article assumes that the reader has some prior knowledge of XML and XSL. XSL provides infrastructure for sorting on character and numerical values. But nothing is provided for sorting date. This article presents two ways for sorting XML data based on date.
First Way by Numerical Method
Let's say you have an XML data as follows:
<Root>
<Element StartDate="26 January 2003"/>
<Element StartDate="28 Feburary 1979"/>
<Element StartDate="3 November 1989"/>
<Element StartDate="1 July 2003"/>
<Element StartDate="26 January 1977"/>
</Root>
(Section a)
You can sort it by having one more attribute for each Element
node which will have the following format "yyyymmdd
". For example: if the date is 26 January 2003
, then the format will be "20030126
". 2003
is the year, 01
is the month and finally 26
is the date. So let's have one more attribute called SortDate
, so our above XML will look like:
<Root>
<Element StartDate="26 January 2003" SortDate="20030126"/>
<Element StartDate="28 Feburary 1979" SortDate="19790228"/>
<Element StartDate="3 November 1989" SortDate="19891103"/>
<Element StartDate="1 July 2003" SortDate="20030701"/>
<Element StartDate="26 January 1977" SortDate="19770126"/>
</Root>
Note: Month name and day which are less than 10 should be denoted by two numeric values, otherwise it will affect the sort order, resulting in wrong results. For example: January
should be denoted by "01
".
Now sort the XML data with respect to SortDate
attribute and sorting using numerical data.
<xsl:sort select="@SortDate" data-type="numeric" order="descending"/>
Second Way by String Method
To explain how this method works, let me first give you code which will be used to sort the above XML data (Section a) by this method.
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="http://www.w3.org/1999/XSL/Format">
<xsl:variable name="vMonthNames"
select="'|January|February|March|April|May|June|July|
August|September|October|November|December'"/>
<xsl:template match="/">
<xsl:for-each select="Root/Element">
<!-- year part -->
<xsl:sort
select="substring-after(substring-after(@Startdate,' '),' ')"
data-type="number"/>
<!-- month part -->
<xsl:sort
select="string-length(substring-before($vMonthNames,
substring-before(substring-after(@Startdate,' '),' ')))"
data-type="number"/>
<!-- day part -->
<xsl:sort select="substring-before(@Startdate,' ')"
data-type="number"/>
<xsl:value-of select="@date"/><br/>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
The idea is extract the year part of the date and sort the date values using year, then extract the month part of the date and find the month string
in the variable vMonthNames
, you will find the index and that index is used to sort the month. For example, if you find "January
", you will get the index as '1
' and if you find "March
", you will get an index 18
. This is how "January
" is less than "March". And finally extract the day part from the date and sort on it.
License
This article has no explicit license attached to it, but may contain usage terms in the article text or the download files themselves. If in doubt, please contact the author via the discussion board below. A list of licenses authors might use can be found here.