xsl-list
[Top] [All Lists]

Re: comparing timestamps

2003-03-12 22:44:56
walter(_dot_)crockett(_at_)ascentialsoftware(_dot_)com wrote:
Hello,
      I need to identify the five most recent objects by their timestamp
and then display them in order from newest to oldest.

      For example the value for @CreationDate is 2003-02-12 11:10:44
      Is there a common routine for parsing this into a number that can be
compared with other numbers and then sorted?

If they're all in that format, and the middle number in the date is the month,
then they're comparable as strings; no conversion necessary.

And while we're at it, a common routine for comparing and sorting?

<xsl:sort/> can define an order in which the nodes selected in an
xsl:apply-templates or xsl:for-each are to be processed. It can handle sorting
on strings as well as on numeric values, and possibly others, if the processor
defines them. See "Sorting" in the XSLT 1.0 spec for details.

If your XSLT processor has an exsl:node-set() or equivalent extension function
for converting a result tree fragment to a node-set, you can process the
elements in sorted order, copying them to a result tree fragment, which is
then converted to a node-set that you can get the first 5 items from:

<xsl:variable name="sorted">
  <xsl:for-each select="Item">
    <xsl:sort select="@CreationDate" order="descending"/>
    <xsl:copy-of select="."/>
  </xsl:for-each>
</xsl:variable>
<xsl:variable name="firstfive" select="exsl:node-set($sorted)/Item[position() 
&lt; 6]"/>

The simple use of position() in the predicate is likely to be optimized by the
processor (so only the first 6 items are even looked at), but the overhead of
creating and converting the RTF is going to offset this efficiency.

A pure XSLT 1.0 solution is to avoid creating an RTF and just process the
nodes in sorted order, only taking action when the position is less than 6:

<xsl:for-each select="Item">
  <xsl:sort select="@CreationDate" order="descending"/>
  <xsl:if test="position() &lt; 5">
    ...do something...
  </xsl:if>
</xsl:for-each>

The downside is that you can be certain that the processor won't optimize;
it'll have to evaluate the xsl:if for every node. Another caveat with this
approach is that the nodes remain in document order, which may or may not be
desirable. For example, in the "do something", following-sibling::Item[1] will
identify the next Item from the original, unsorted list of Items...

There's a ton of info in the XSLT FAQ under "Sorting" and "Sorting and
Grouping" at http://www.dpawson.co.uk/

Also see Jeni Tennison's collection of XSLT info at
http://www.jenitennison.com/

Mike

-- 
  Mike J. Brown   |  http://skew.org/~mike/resume/
  Denver, CO, USA |  http://skew.org/xml/

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



<Prev in Thread] Current Thread [Next in Thread>