XSLT 1.0:从给定的日期和时间中查找最大值

时间:2015-05-14 18:54:50

标签: xml xslt xslt-1.0

大家好,
     我有以下格式的xml事件(月,日,年,小时,分钟,秒AM / PM)。我想提一下,我无法控制生成的XML。现在我需要找到最大或最新的" dateevent"并选择相应的" 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中,我必须选择最新的&#34; dateevent&#34;(即)4/29/2015 6:55:58 PM并选择相应的&#34; eventname&#34;(ieTest2) 。有关如何做到这一点的任何建议..?应用程序使用SAX解析器进行转换。我试过排序方法,但我没有成功。 我的结果应该是

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

有关如何处理的任何建议?

由于

1 个答案:

答案 0 :(得分:0)

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

  1. 将您的日期转换为YYYMMDDhhmmss形式的可排序字符串。将12小时时间转换为24小时格式的必要性使这变得更加复杂。
  2. 对结果节点进行排序,并输出其中一个节点的第一个(或最后一个,具体取决于排序顺序)。
  3. 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>