Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Filter xml nodes on date

Status
Not open for further replies.

Muddmuse

Programmer
Jul 31, 2001
85
US
I have an xml document containing a list of 'Events' which ultimately gets presented to end users. How can I filter out data whose date is in the past?

<Events>
<Event>
<Date>08/24/06</Date>
</Event>
<Event>
<Date>09/24/06</Date>
</Event>
</Events>
 
[1] Using short year yy format can cause problem no end. Better use long year ccyy format. If that's legacy, just pay more attention to epoche year-zero.

[2] The main problem ironically is the "today"/"now". Using xsl without extension, one cannot set the today automatically.

Let me illustrate the approach for [1] ccyy year and [2] hard coded "today". The xsl transform the original document into including only future (including today) events.

Let's say the xml source file:
[tt]
<Events>
<Event>
<Date>08/24/2006</Date>
</Event>
<Event>
<Date>09/24/2006</Date>
</Event>
<!-- this is added, it is today event -->
<Event>
<Date>09/04/2006</Date>
</Event>
</Events>
[/tt]
The xsl source file can be scripted like this.
[tt]
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="<xsl:eek:utput method="xml" encoding="utf-8" indent="yes" />
<!-- hardcoded version -->
<xsl:param name="date_now" select="'09/04/2006'" />

<xsl:template match="Events">
<xsl:copy>
<xsl:apply-templates select="Event">
<xsl:with-param name="ccyy_now" select="substring($date_now,7,4)" />
<xsl:with-param name="mm_now" select="substring($date_now,1,2)" />
<xsl:with-param name="dd_now" select="substring($date_now,4,2)" />
</xsl:apply-templates>
</xsl:copy>
</xsl:template>

<xsl:template match="Event">
<xsl:param name="ccyy_now" />
<xsl:param name="mm_now" />
<xsl:param name="dd_now" />
<xsl:variable name="ccyy_event" select="substring(Date,7,4)" />
<xsl:variable name="mm_event" select="substring(Date,1,2)" />
<xsl:variable name="dd_event" select="substring(Date,4,2)" />
<xsl:if test="boolean(number($ccyy_event) &gt; number($ccyy_now))">
<xsl:copy-of select="." />
</xsl:if>
<xsl:if test="boolean(number($ccyy_event) = number($ccyy_now))">
<xsl:if test="boolean(number($mm_event) &gt; number($mm_now))">
<xsl:copy-of select="." />
</xsl:if>
</xsl:if>
<xsl:if test="boolean(number($ccyy_event) = number($ccyy_now)) and boolean(number($mm_event) = number($mm_now))">
<xsl:if test="boolean(number($dd_event) &gt;= number($dd_now))"> <!-- including today (=) -->
<xsl:copy-of select="." />
</xsl:if>
</xsl:if>
</xsl:template>

</xsl:stylesheet>
[/tt]
It can thereby easily generalized to retrieve the past rather than the future. Generalization can be investigated on the coding design as well. In any case, that shows the essential for the purpose.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top