|
next
|
 Subject: Sorting XSL and limiting only first n elements Author: N T Date: 01 Aug 2005 02:47 PM
|
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:01:00 AM</lastupdated>
<title>News from aerospace</title>
</news>
<news>
<industry>Mechanical</industry>
<lastupdated>6/28/2004 12:01:00 AM</lastupdated>
<title>News from mechanical</title>
</news>
<news>
<industry>Aerospace</industry>
<lastupdated>4/2/2002 12:01:00 PM</lastupdated>
<title>News from aerospace</title>
</news>
<news>
<industry>Electrical</industry>
<lastupdated>3/8/2005 12: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 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:
<xsl:template match="/">
<xsl:for-each select="root/news">
<!-- 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="industry/text() = 'Aerospace' or
industry/text() = 'Electrical'
">
<!-- <xsl:if test="position() < 2"> -->
<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:if>
</xsl:for-each>
</xsl:template>
|
next
|
 Subject: Sorting XSL and limiting only first n elements Author: N T Date: 02 Aug 2005 11:03 AM
|
Thanks a lot Song. That worked fine.
I just had 2 follow-up questions:
1) Is there a way I can make it faster (I read somewhere that I could use keys, just don't know how to?)
2) Also, in my sorting by lastupdated, I have an error, where 12:01 AM is being displayed ahead of 9:20 AM (in reverse chronological order), which is incorrect. I am sorting YYYY first (as number), then MM (as number), date (as number), AM/PM (as string descending), HH (as number), MI (as number). Is there a way to correct that?
Thanks.
|
|
|
|