Hari
Hari

Reputation: 397

Finding first, second and third highest date time variables from given three date variables in xslt 2.0 or xslt 1.0

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

Answers (1)

michael.hor257k
michael.hor257k

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?


Edit:

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)[. &lt; $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

Related Questions