RE: [xsl] Re: XSL:sort dates as numbers gets incorrect results

Subject: RE: [xsl] Re: XSL:sort dates as numbers gets incorrect results
From: "Michael Kay" <mike@xxxxxxxxxxxx>
Date: Mon, 31 Oct 2005 17:15:08 -0000
I would certainly do it as a two-phase transformation. You can either do a
2-phase transformation within a single stylesheet, or by writing two
stylesheets and running them in a pipeline. My preference would be for the
latter approach, since you will then find that the first transformation (the
one that converts dates to ISO format) is reusable in other applications
that need to process the same data. But there are some environments where
it's operationally more convenient to use a single stylesheet. (Google for
"XSLT multiphase transformations") for examples of how to do this.

Michael Kay
http://www.saxonica.com/ 

> -----Original Message-----
> From: Ninad Tambe [mailto:ninadtambe@xxxxxxxxx] 
> Sent: 31 October 2005 16:48
> To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
> Subject: [xsl] Re: XSL:sort dates as numbers gets incorrect results
> 
> Michael,
> Thanks for your response. Let me start by saying that
> I don't have control over the XML data itself. Now,
> are you suggesting that I change the dates of all the
> 200 odd nodes dynamically and save it in another
> Document (java object) and process it with the
> stylesheet, or is there is a way to do that within
> XSL?
> 
> 
> Date: Fri, 28 Oct 2005 23:52:00 +0100
> To: <xsl-list@xxxxxxxxxxxxxxxxxxxxxx>
> From: "Michael Kay" <mike@xxxxxxxxxxxx>
> Subject: RE: [xsl] XSL:sort dates as numbers gets
> incorrect results
> 
> I would tackle this by first transforming the document
> to use ISO 
> date/time
> formats, then sorting, then (if you really must)
> converting back into 
> the
> peculiar US format.
> 
> Michael Kay
> http://www.saxonica.com/
> 
> > -----Original Message-----
> > From: Ninad Tambe [mailto:ninadtambe@xxxxxxxxx] 
> > Sent: 28 October 2005 20:25
> > To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
> > Subject: [xsl] XSL:sort dates as numbers gets
> incorrect results
> > 
> > I have an XML document that have about 200 nodes
> that
> > look roughly like this:
> > 
> > <root>
> > <news>
> > <industry>Aerospace</industry>
> > <lastupdated>7/28/2005 12:10:00 PM</lastupdated>
> > <title>News from aerospace</title>
> > </news>
> > <news>
> > <industry>Mechanical</industry>
> > <lastupdated>7/28/2005 12:23:00 AM</lastupdated>
> > <title>News from mechanical</title>
> > </news>
> > <news>
> > <industry>Aerospace</industry>
> > <lastupdated>7/28/2005 9:12:00 PM</lastupdated>
> > <title>News from aerospace</title>
> > </news>
> > <news>
> > <industry>Electrical</industry>
> > <lastupdated>7/28/2005 6:01:00 AM</lastupdated>
> > <title>News from electrical</title>
> > </news>
> > <news>
> > <industry>Computer Science</industry>
> > <lastupdated>3/28/2002 12:01:00 AM</lastupdated>
> > <title>News from CS</title>
> > </news>
> > <news>
> > <industry>Aerospace</industry>
> > <lastupdated>4/28/2005 12:01:00 AM</lastupdated>
> > <title>News from aerospace</title>
> > </news>
> > </root>
> > 
> > I need to display top 3 items in reverse
> chronological
> > order that have either Aerospace or Electrical as
> > industry. I need the first 2 (assuming they are
> sorted
> > by lastupdated).
> > 
> > I need to sort these nodes where industry is
> Aerospace
> > or Electrical (for example), sort them by
> lastupdated
> > (reverse chronological). I am able to do that so far
> > successfully. Its just that I need to display the
> top
> > 2 items (of the 3 or more that are selected). How do
> I
> > accomplish that? I cannot use the position(),
> because
> > it relates to the nodes in the document, not the
> > position of nodes after sort.
> > 
> > Here is the XSL:
> > 
> > <?xml version='1.0'?>
> > <xsl:stylesheet version="1.0"
> > xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>
> > 
> > <xsl:template match="/">
> > <table>
> > <xsl:for-each select="root/news[industry/text() =
> > 'Aerospace' or
> > industry/text() = 'Electrical']
> > "> 
> > 
> > <!-- lastupdated is MM/DD/YYYY HH:MI:SS XM e.g.
> > 7/27/2005 4:12:22 PM -->
> > <xsl:sort order="descending" data-type="number"
> >
> select='substring-after(substring-after(substring-before(LASTUPDATED,
> > " "), "/"), "/")'></xsl:sort>
> > <!-- sort the yyyy as number -->
> > <xsl:sort order="descending" data-type="number"
> >
> select='substring-before(substring-before(LASTUPDATED,
> > " "), "/")'></xsl:sort>
> > <!-- sort MM as number -->
> > <xsl:sort order="descending" data-type="number"
> >
> select='substring-after(substring-before(LASTUPDATED,
> > " "), "/")'></xsl:sort>
> > <!-- sort date as number -->
> > <xsl:sort order="descending"
> > select='substring-after(substring-after(LASTUPDATED,
> "
> > "), " ")'></xsl:sort>
> > <!-- within day, sort XM (AM/PM) as string, PM first
> > -->
> > <xsl:sort order="descending" data-type="number"
> >
> select='substring-before(substring-after(LASTUPDATED,
> > " "), ":")'></xsl:sort>
> > <!-- sort the HH as number -->
> > <xsl:sort order="descending" data-type="number"
> >
> select='substring-before(substring-after(substring-after(LASTUPDATED,
> > " "), ":"), ":")'></xsl:sort>
> > <!-- sort the MM as number --> 
> > <!-- The one problem currently with this approach is
> > that 12:20 AM will be considered latest when
> compared
> > to 9:20 AM -->
> > 
> > <xsl:if test="position() &lt; 4">
> > 
> > 		<tr><td>
> > 			<xsl:value-of
> >
> select='concat(substring-before(substring-after(lastupdated,
> > " "), ":"), ":",
> >
> substring-before(substring-after(substring-after(lastupdated,
> > " "), ":"), ":"), " ",
> > substring-after(substring-after(lastupdated, " "), "
> > "), " ET, ", substring-before(lastupdated, " "))' />
> 
> > 			
> > 		</td></tr>
> > 
> > <tr><td>
> > <xsl:value-of select="title"/>
> > </td></tr>
> > </xsl:if> 
> > 
> > </xsl:for-each>
> > </table>
> > </xsl:template>
> > 
> > </xsl:stylesheet>
> > 
> > 
> > I get the results fine, but the problem I have is
> that
> > 12:10:00 PM comes before 9:12:00 PM, which is
> > incorrect (reverse chronological). Same behavior for
> > 12:23:00 AM displaying before 6:01:00 AM.
> > 
> > Please help.
> > 
> > 
> > 
> > 
> > 	
> > 		
> > __________________________________ 
> > Yahoo! Mail - PC Magazine Editors' Choice 2005 
> > http://mail.yahoo.com
> > 
> > 
> 
> 
> 
> 		
> __________________________________ 
> Yahoo! FareChase: Search multiple travel sites in one click.
> http://farechase.yahoo.com

Current Thread