我的任务是使用不同的日期格式转换生成的XML文件 作为排序标准。作为XSLT的新手,我想知道是否可以使用单个转换统一日期格式并进行排序。
源XML的示例如下:
<?xml version="1.0"?>
<summary>
<incoming>
<delivery incDate="2013-11-08"/>
</incoming>
<outgoing>
<delivery outDate="20131108"/>
</outgoing>
<repairs>
<repair repairDate="2013-11-08 11:25:34"/>
</repairs>
</summary>
这就是我想要实现的目标:
<?xml version="1.0"?>
<summary>
<actions>
<action type="incoming" dateTime="2013-11-08 00:00:00"/>
<action type="repair" dateTime="2013-11-08 11:25:34"/>
<action type="outgoing" dateTime="2013-11-08 23:59:59"/>
</actions>
</summary>
我做了什么?
<incoming>
的孩子添加时间00:00:00。<outgoing>
的孩子身上加上23:59:59的时间。答案 0 :(得分:2)
在XSLT 2.0中,这非常简单,因为您可以使用两遍方法,首先生成所需的输出然后对它们进行排序:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output method="xml" indent="yes" />
<xsl:template match="/">
<summary>
<actions>
<xsl:perform-sort>
<xsl:sort select="@dateTime" />
<xsl:apply-templates select="summary/*/*" />
</xsl:perform-sort>
</actions>
</summary>
</xsl:template>
<xsl:template match="incoming/delivery">
<action type="incoming" dateTime="{@incDate} 00:00:00"/>
</xsl:template>
<xsl:template match="outgoing/delivery">
<action type="outgoing" dateTime="{substring(@outDate, 1, 4)}-{substring(@outDate, 5, 2)}-{substring(@outDate, 7, 2)} 23:59:59"/>
</xsl:template>
<xsl:template match="repairs/repair">
<action type="repair" dateTime="{@repairDate}"/>
</xsl:template>
</xsl:stylesheet>
在这里,我们使用apply-templates
和然后使用XPath表达式{{1}对perform-sort
生成的元素进行排序,为每个输入元素生成输出。相对于生成的XML而不是原始的。
如果您限制为1.0,则这不是一个选项,因为您只能根据输入XML中的内容进行排序,而不是根据生成的输出进行排序。因此,我们需要提出一个XPath 1.0表达式,它可以处理三种日期格式中的任何一种并生成合适的排序键
@dateTime
这使用了许多技巧,最值得注意的是
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" indent="yes" />
<xsl:template match="/">
<summary>
<actions>
<xsl:apply-templates select="summary/*/*">
<xsl:sort select="
translate(
concat(
@incDate, @outDate, @repairDate,
substring('000000', 6*not(@incDate) + 1),
substring('235959', 6*not(@outDate) + 1)
),
'-: ',
''
)" />
</xsl:apply-templates>
</actions>
</summary>
</xsl:template>
<!-- the other three templates are unchanged -->
依赖于许多事情:
substring('000000', 6*not(@incDate) + 1)
的参数被视为布尔值。因此,如果目标节点具有not()
属性,则返回字符串000000
,如果不具有incDate
属性,则返回空字符串。最终的concat
为YYYY-MM-DD000000
建立一个字符串incDate
,YYYYMMDD235959
为outDate
,{YYYY-MM-DD HH:mm:ss
为repairDate
1}},translate
删除所有空格,连字符和冒号,以将这三种格式化为可以按字典顺序进行比较的通用格式。