Reputation: 397
I have three date time variables and I need to find first, second and third highest.
Here is the actual requirement
Step 1 : Get the first highest date & time (out of three) and it should be less than current date time + 1 month. If yes, consider the first highest else step 2.
Step 2 : Get the second highest date & time (out of two) and it should be less than current date time + 1 month. If yes, consider the second highest else step 3.
Step 3 : Get the third date & time and it should be less than current date time + 1 month. If yes, consider the third highest else return NULL.
I am sure my code below is really annoying but advice/support is appreciated.
<xsl:template match="SUBSCRIBER">
<xsl:variable name="first_date_time" as="xs:dateTime" select="xs:dateTime('2014-08-20T00:00:00')"/>
<xsl:variable name="second_date_time" as="xs:dateTime" select="xs:dateTime('2014-08-21T00:00:00')"/>
<xsl:variable name="third_date_time" as="xs:dateTime" select="xs:dateTime('2014-08-18T00:00:00')"/>
<xsl:variable name="product">
<xsl:perform-sort select="./.">
<xsl:sort select="$first_date_time"/>
<xsl:sort select="$second_date_time"/>
<xsl:sort select="$third_date_time"/>
</xsl:perform-sort>
</xsl:variable>
<xsl:copy-of select="$product"/>
</xsl:template>
</xsl:stylesheet>
Upvotes: 0
Views: 282
Reputation: 117165
Couldn't you simply take all the given dates that are less than a month away, sort them and take the first three of the result?
For example, consider the following stylesheet:
XSLT 2.0
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="/">
<xsl:variable name="first_date_time" as="xs:dateTime" select="xs:dateTime('2014-08-15T00:00:00')"/>
<xsl:variable name="second_date_time" as="xs:dateTime" select="xs:dateTime('2014-09-15T00:00:00')"/>
<xsl:variable name="third_date_time" as="xs:dateTime" select="xs:dateTime('2014-10-15T00:00:00')"/>
<xsl:variable name="cut-off-date" select="current-dateTime() + xs:yearMonthDuration('P1M')" as="xs:dateTime"/>
<xsl:variable name="qualifying-dates" as="xs:dateTime*">
<xsl:perform-sort select="($first_date_time, $second_date_time, $third_date_time)[. < $cut-off-date]">
<xsl:sort select="xs:dateTime(.)" order="descending"/>
</xsl:perform-sort>
</xsl:variable>
<!-- output -->
<output>
<xsl:for-each select="$qualifying-dates" >
<date><xsl:value-of select="." /></date>
</xsl:for-each>
</output>
</xsl:template>
</xsl:stylesheet>
If applied today (2014-08-20) to any XML input, the result will be:
<?xml version="1.0" encoding="UTF-8"?>
<output>
<date>2014-09-15T00:00:00</date>
<date>2014-08-15T00:00:00</date>
</output>
As you can see, the date that is more than one month away is excluded from the output, and the remaining dates are ordered in descending order - so that the first returned date is the latest date that's still less than a month away.
Upvotes: 1