0

Hi all,
I have the xml event in the following format (month,date,year,hour,minute,seconds AM/PM). I would like to mention that, I don't have the control over the generated XML. Now I need to find the maximum or latest "dateevent" and select the corresponding "eventname". The XML looks like

                            <?xml version="1.0"  standalone="no"?>
                            <day>
                                <day-event>
                                    <eventname>Test1</eventname>
                                    <dateevent>1/30/2014 7:15:50 AM</dateevent>
                                </day-event>
                                <day-event>
                                    <eventname>Test2</eventname>
                                    <dateevent>4/29/2015 6:55:58 PM</dateevent>
                                </day-event>
                                <day-event>
                                    <eventname>Test3</eventname>
                                    <dateevent>12/29/2014 9:33:24 PM</dateevent>
                                </day-event>
                            </day>

In this XML I have to select the latest "dateevent"(ie) 4/29/2015 6:55:58 PM and also select the corresponding "eventname"(ieTest2). Any suggestions on how to do this..? Application uses SAX parser to make the transformation. I tried sorting approach but I wasn't successful. My result should look like

eventname 4/29/2015 6:55:58 PM

Any suggestions on how to approach ?

Thanks

1 Answers1

0

XSLT 1.0 has no concept of dates (and even XSLT 2.0 only recognize dates in ISO-8601 format). So you need to do this in two steps:

  1. Convert your dates to a sortable string in the form of YYYMMDDhhmmss. This is further complicated by the necessity to convert 12-hour time to 24-hour format.
  2. Sort the resulting nodes and output the first (or last, depending on the sort order) one of these.

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:exsl="http://exslt.org/common"
extension-element-prefixes="exsl">
<xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes"/>

<xsl:template match="/day">
    <!-- first pass -->
    <xsl:variable name="events">
        <xsl:for-each select="day-event">
            <event name="{eventname}" date="{dateevent}">
                <xsl:call-template name="convert-date">
                    <xsl:with-param name="datestring" select="dateevent"/>
                </xsl:call-template>
            </event>
        </xsl:for-each>
    </xsl:variable>
    <!-- output -->
    <output>
        <xsl:for-each select="exsl:node-set($events)/event">
            <xsl:sort select="." order="descending"/>
            <xsl:if test="position()=1">
                <eventname>
                    <xsl:value-of select="@name" />
                </eventname>
                <dateevent>
                    <xsl:value-of select="@date" />
                </dateevent>
            </xsl:if>
        </xsl:for-each>
    </output>
</xsl:template>

<xsl:template name="convert-date">
    <xsl:param name="datestring"/>

    <xsl:variable name="date" select="substring-before($datestring, ' ')" />
    <xsl:variable name="time" select="substring-before(substring-after($datestring, ' '), ' ')" />

    <xsl:variable name="M" select="substring-before($date, '/')" />
    <xsl:variable name="D" select="substring-before(substring-after($date, '/'), '/')" />
    <xsl:variable name="Y" select="substring-after(substring-after($date, '/'), '/')" />

    <xsl:variable name="h12" select="substring-before($time, ':')"/>
    <xsl:variable name="m" select="substring-before(substring-after($time,':'), ':')"/>
    <xsl:variable name="s" select="substring-after(substring-after($time,':'), ':')"/>

    <xsl:variable name="pm" select="contains($datestring,'PM')"/>    
    <xsl:variable name="h" select="$h12 mod 12 + 12*$pm"/>

    <xsl:value-of select="format-number($Y, '0000')" />
    <xsl:value-of select="format-number($M, '00')" />
    <xsl:value-of select="format-number($D, '00')" />
    <xsl:value-of select="format-number($h, '00')" />
    <xsl:value-of select="format-number($m, '00')" />
    <xsl:value-of select="format-number($s, '00')" />
</xsl:template>

</xsl:stylesheet>

Result

?xml version="1.0" encoding="utf-8"?>
<output>
  <eventname>Test2</eventname>
  <dateevent>4/29/2015 6:55:58 PM</dateevent>
</output>
Daniel Haley
  • 51,389
  • 6
  • 69
  • 95
michael.hor257k
  • 113,275
  • 6
  • 33
  • 51
  • I'm getting an error " prefix 'exsl' is not defined". I tried to download the package at http://exslt.org/download.html . I'm getting 404 .. should I download any other package ? – still_learning May 14 '15 at 20:12
  • There is nothing to download. Which XSLT processor are you using? And what is the **exact** error message? You should not be seeing an error, if you have declared the `exsl:` namespace as I did in my example. – michael.hor257k May 14 '15 at 20:16
  • I haven't declared "exsl:" namespace that's why I got that error. I don't know, I am not getting any error in this code but the third party application is not executing anything after this line of code "". Thanks for your help though :) – still_learning May 15 '15 at 13:29
  • @user3533257 Which XSLT processor is the application using? See here how to find out: http://stackoverflow.com/questions/25244370/how-can-we-check-that-which-xslt-processor-uses-as-default-in-solr/25245033#25245033 – michael.hor257k May 15 '15 at 15:16
  • The XSLT processor name is : Apache Software Foundation and the version number is:1 – still_learning May 19 '15 at 12:38
  • @user3533257 Xalan (the Apache XSLT processor) supports the EXSLT node-set() extension function. However, it's possible that your application uses an old and buggy version. In such case, I don't know how to help you. – michael.hor257k May 19 '15 at 15:25
  • I think so. Thanks for your time :) I don't have enough points to give a up-vote for your answer, but looks like it will work though. – still_learning May 19 '15 at 18:51
  • @user3533257 If it works, please close the question by accepting the answer. – michael.hor257k May 19 '15 at 19:41