Home > Mobile >  How to sort the date using XSLT in given format
How to sort the date using XSLT in given format

Time:07-01

I have xml like below

<Root>
  <Element StartDate="2013/12/24"/>
  <Element StartDate="2013/12/20"/>
  <Element StartDate="2013/12/31"/>
  <Element StartDate="2013/12/30"/>
</Root>

How do I get only max date from it using xslt 1.0. Format is YYYY/MM/DD

<Root>
  <Element StartDate="2013/12/31"/>
</Root>

CodePudding user response:

YYYY/MM/DD dates will sort correctly (i.e. in chronological order) when the sort order is alphabetical. To get the latest date, you can do simply:

<xsl:template match="/Root">
    <latest-date>
        <xsl:for-each select="Element">
            <xsl:sort select="@StartDate" data-type="text" order="descending" />
            <xsl:if test="position()=1">
                <xsl:value-of select="@StartDate" />
            </xsl:if>
        </xsl:for-each>
    </latest-date>
</xsl:template>

Note that this is assuming that the format is indeed YYYY/MM/DD - that is with leading zeros for month and day. Your example is ambiguous in this respect.

CodePudding user response:

If it turns out there are day or months numbers without leading zeros (e.g. dates like 2020/8/6 or 2019/5/12), then you can use multiple xsl:sort elements to sort the dates first by year, then by month, and then by day, by extracting the 3 different parts of each date, and by telling xsl:sort to treat the results as numbers (rather than strings) because e.g. 5 comes before 10 numerically, but after it in alphabetical order.

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

<xsl:template match="/Root">
    <latest-date>
        <xsl:for-each select="Element">
            <!-- sort by year... -->
            <xsl:sort select="substring-before(@StartDate, '/')" 
                      data-type="number" order="descending" />
            <!-- ... then by month -->
            <xsl:sort select="substring-before(substring-after(@StartDate, '/'), '/')" 
                      data-type="number" order="descending" />
            <!-- ... then by day -->
            <xsl:sort select="substring-after(substring-after(@StartDate, '/'), '/')" 
                      data-type="number" order="descending" />
            <xsl:if test="position()=1">
                <xsl:value-of select="@StartDate" />
            </xsl:if>
        </xsl:for-each>
    </latest-date>
</xsl:template>

</xsl:stylesheet>
  • Related