I simply need to select the most recent list of item (by date). The XML contains
multiple lists, in any order and will contain "future" items. The dates are converted
to UTC basic format (CCYYMMDD) so they can be treated as ordinary numbers. So the
logic is essentially, sort the list by "date", then select the last() item
where date is less than "now".
I can only get it to work if I do it in two steps (See Method #2 below). But this
means that each list node needs to be tested. Does this create any additional
overhead? Can it be done in one step?
<schedule>
<list date="20041231">
<item title="Ancient #1"/>
<item title="Ancient #2"/>
<item title="Ancient #3"/>
</list>
<list date="20050515">
<item title="Future #1"/>
<item title="Future #2"/>
<item title="Future #3"/>
</list>
<list date="20050507">
<item title="Current #1"/>
<item title="Current #2"/>
<item title="Current #3"/>
</list>
<list date="20050505">
<item title="Recent #1"/>
<item title="Recent #2"/>
<item title="Recent #3"/>
</list>
</schedule>
<xsl:stylesheet version="1.0" xmlns:xsl="
http://www.w3.org/1999/XSL/Transform" >
<xsl:param name="now">20050511</xsl:p
aram>
<xsl:template match="//schedule">
Method #1 Doesn't work because the sort happens after the select<br/>
<xsl:apply-templates select="list[@date < $now][last()]/item">
<xsl:sort select="@date"/>
</xsl:apply-templates>
<hr/>
Method #2 Works: but it needs two steps. Can it be done together?<br/>
<xsl:apply-templates select="list[@date < $now]">
<xsl:sort select="@date"/>
</xsl:apply-templates>
</xsl:template>
<xsl:template match="list">
Test if current node is last().
<xsl:if test="position() = last()">
<xsl:apply-templates select="item"/>
</xsl:if>
</xsl:template>
<xsl:template match="item">
<xsl:value-of select="@title"/><br/>
</xsl:template>
</xsl:stylesheet>
Start Free Trial