使用XSLT排序日期无法正常工作

时间:2017-09-18 15:04:51

标签: xml sorting date xslt

我有一个要求,我需要根据日期对不同的XML块进行排序,并将它们放在不同的标签中。到目前为止,我能够使用数字实现这一目标。但每当我尝试按日期对其进行排序时,它都无法正常工作。我也尝试了不同的数据类型。但是没有成功。任何指针都会很棒。

XML:

response status="200">
        <classes>
            <classdetsils>
                <name>Learn12</name>
                <date1>20161115</date1>
            </classdetsils>
            <classdetsils>
                <name>Learn12</name>
                <date1>20161114</date1>
            </classdetsils>
            <classdetsils>
                <name>Learn13</name>
                <date1>20161117</date1>
            </classdetsils>
            <classdetsils>
                <name>Learn14</name>
                <date1>20161116</date1>
            </classdetsils>
            <classdetsils>
                <name>Learn15</name>
                <date1>20161113</date1>
            </classdetsils>
        </classes>
    </response>

XSLT:

<xsl:stylesheet version="2.0"  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"  xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dp="http://www.datapower.com/extensions"  extension-element-prefixes="dp"  exclude-result-prefixes="dp">
<xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes"/>
<xsl:variable name="vN" select="20161116"/>
<xsl:template match="/">
    <test1>
        <a>
            <xsl:apply-templates select="response/classes/classdetsils[date1 &gt; $vN]" />
            <xsl:sort order="ascending" select="date1" data-type="number"/>
        </a>
        <b>
            <xsl:apply-templates select="response/classes/classdetsils[date1 &lt; $vN]" />
            <xsl:sort order="ascending" select="date1" data-type="number"/>
        </b>
    </test1>
</xsl:template>
<xsl:template match="classdetsils">
    <name>
        <xsl:value-of select="name" />
    </name>
    <date>
        <xsl:value-of select="date1" />
    </date>
</xsl:template></xsl:stylesheet>

输出:

<test1 xmlns:xs="http://www.w3.org/2001/XMLSchema" >
<a>
    <name>Learn13</name>
    <date>20161117</date>
</a>
<b>
    <name>Learn12</name>
    <date>20161115</date>
    <name>Learn12</name>
    <date>20161114</date>
    <name>Learn15</name>
    <date>20161113</date>
</b></test1>

这很好用,因为date1字段现在是一个数字。但是,如果我将date1的值更改为XML中的xs:date类型,即:20161115变为2016-11-15并且也在XSLT中进行更改,它似乎不起作用。所以XML变成了:

response status="200">
    <classes>
        <classdetsils>
            <name>Learn12</name>
            <date1>2016-11-15</date1>
        </classdetsils>
        <classdetsils>
            <name>Learn12</name>
            <date1>2016-11-14</date1>
        </classdetsils>
        <classdetsils>
            <name>Learn13</name>
            <date1>2016-11-17</date1>
        </classdetsils>
        <classdetsils>
            <name>Learn14</name>
            <date1>2016-11-16</date1>
        </classdetsils>
        <classdetsils>
            <name>Learn15</name>
            <date1>2016-11-13</date1>
        </classdetsils>
    </classes>
</response>

XSLT是:

<xsl:stylesheet version="2.0"  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"  xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dp="http://www.datapower.com/extensions"  extension-element-prefixes="dp"  exclude-result-prefixes="dp">
<xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes"/>
<xsl:variable name="vN" select="2016-11-16"/>
<xsl:template match="/">
    <test1>
        <a>
            <xsl:apply-templates select="response/classes/classdetsils[date1 &gt; $vN]" />
            <xsl:sort order="ascending" select="date1" data-type="number"/>
        </a>
        <b>
            <xsl:apply-templates select="response/classes/classdetsils[date1 &lt; $vN]" />
            <xsl:sort order="ascending" select="date1" data-type="number"/>
        </b>
    </test1>
</xsl:template>
<xsl:template match="classdetsils">
    <name>
        <xsl:value-of select="name" />
    </name>
    <date>
        <xsl:value-of select="date1" />
    </date>
</xsl:template></xsl:stylesheet>

输出变为空:

<test1 xmlns:xs="http://www.w3.org/2001/XMLSchema" >
<a />
<b /></test1>

我认为我对数据类型犯了一些愚蠢的错误。任何指针都会有所帮助。

干杯!

2 个答案:

答案 0 :(得分:1)

首先,xsl:sort需要是xsl:apply-templates的子项,xs:date格式不能作为数字排序,而只能作为字符串或(假设)支持XSLT / XPath 2.0)为xs:date

       <xsl:apply-templates select="response/classes/classdetsils[date1 &gt; $vN]">
        <xsl:sort order="ascending" select="xs:date(date1)"/>
       </xsl:apply-templates>

但是,根据您当前的代码,您需要确保将日期作为字符串传递并转换为xs:date并更改谓词:

<xsl:param name="vN" select="'2016-11-16'"/>
<xsl:variable name="vD" select="xs:date($vN)"/>

<xsl:template match="/">
    <test1>
        <a>
            <xsl:apply-templates select="response/classes/classdetsils[xs:date(date1) &gt; $vD]">
              <xsl:sort order="ascending" select="xs:date(date1)"/>
            </xsl:apply-templates>
        </a>
        <b>
            <xsl:apply-templates select="response/classes/classdetsils[xs:date(date1) &lt; $vD]">
              <xsl:sort order="ascending" select="xs:date(date1)" />
            </xsl:apply-templates>
        </b>
    </test1>
</xsl:template>

然后使用XSLT 2.0处理器,它应该为http://xsltransform.net/jxDigUK处理并为我做。

作为替代方案,排序和比较为字符串(比较我认为也只能用作XSLT / XPath 2.0的字符串):

<xsl:param name="vN" select="'2016-11-16'"/>


<xsl:template match="/">
    <test1>
        <a>
            <xsl:apply-templates select="response/classes/classdetsils[date1 &gt; $vN]">
              <xsl:sort order="ascending" select="date1" data-type="text"/>
            </xsl:apply-templates>
        </a>
        <b>
            <xsl:apply-templates select="response/classes/classdetsils[date1 &lt; $vN]">
              <xsl:sort order="ascending" select="date1" data-type="text" />
            </xsl:apply-templates>
        </b>
    </test1>
</xsl:template>

http://xsltransform.net/naZXpXM

答案 1 :(得分:0)

我能够使用以下方法解决它:

<xsl:apply-templates select="response/classes/classdetsils[number(translate(date1‌​, '-', '')) &gt; number(translate($vN, '-', '')) or number(translate(date1, '-', '')) = number(translate($vN, '-', ''))]"> <xsl:sort order="ascending" select="xs:date(date1)"/> </xsl:apply-templates>

如果有人需要,我可以提供XSLT。