XSLT 1.0:找到给定日期和时间的最大值

XSLT 1.0: find the maximum value from given date and time

大家好,
我有以下格式的 xml 事件(月、日、年、小时、分钟、秒 AM/PM)。我想提一下,我无法控制生成的 XML。现在我需要找到最大或最新的 "dateevent" 和 select 对应的 "eventname"。 XML 看起来像

                            <?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>

在这个XML我要select最新的"dateevent"(ie)4/29/20156:55:58下午还有select相应的"eventname"(即测试 2)。关于如何执行此操作的任何建议..?应用程序使用 SAX 解析器进行转换。我尝试了排序方法,但没有成功。 我的结果应该类似于

事件名称 2015 年 4 月 29 日 6:55:58 下午

有什么处理方法的建议吗?

谢谢

XSLT 1.0 没有日期的概念(甚至 XSLT 2.0 也只能识别 ISO-8601 格式的日期)。所以你需要分两步完成:

  1. 将日期转换为 YYYMMDDhhmmss 格式的可排序字符串。由于需要将 12 小时制转换为 24 小时制,这变得更加复杂。
  2. 对结果节点进行排序并输出其中的第一个(或最后一个,取决于排序顺序)。

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>

结果

?xml version="1.0" encoding="utf-8"?>
<output>
  <eventname>Test2</eventname>
  <dateevent>4/29/2015 6:55:58 PM</dateevent>
</output>