按编辑的属性对元素进行排序
Sorting elements by edited attribute
我正在尝试使用 XSLT 1.0 将两个 XML 文件 "a.xml" 和 "b.xml" 合并到 HTML table 中。这两个文件都包含名为 "event" 的元素,每个元素都有一个 "time" 属性,并附加了一个 dateTime 值。我希望 HTML table 按时间顺序排序。文件 "a.xml" 的时间属性格式正确 (CCYY-MM-DDTHH:MM:SS.msmsms),而 "b.xml" 的时间属性格式不正确 (CCYY-DDDTHH:MM:SS.msmsmsZ),因此我正在使用一些连接和子字符串函数来为 "b.xml" 元素的 "time" 属性构造正确的格式。我现在的问题是:如何使用 "a.xml" 的原始 "time" 属性和 "b.xml" 的更正属性来对 HTML table 的行进行排序?
我已经尝试使用参数来存储格式正确的 "time" 属性。我还尝试使用节点集分两步解决问题(即首先转换 "b.xml" 属性,保存结果,然后从中间文件创建 HTML ),但这两种方法都不起作用我。最后,我尝试在页面加载时使用 JavaScript 对 HTML table 进行排序,但是 table 太大,无法在每次页面加载时以这种方式进行排序。
我很高兴 XSLT 功能的每一个提示都可以帮助我。不过,我必须坚持使用 XSLT1.0,不能将 XSLT2.0 用于该项目。
a.xml
<?xml version="1.0" encoding="UTF-8"?>
<data>
<event time="2019-02-03T06:00:00.000"></event>
<event time="2019-02-01T06:00:00.000"></event>
</data>
b.xml格式化前
<?xml version="1.0" encoding="UTF-8"?>
<data>
<event time="2019-035T06:00:00.000"></event>
<event time="2019-033T06:00:00.000"></event>
</data>
b.xml格式化后
<?xml version="1.0" encoding="UTF-8"?>
<data>
<event time="2019-02-04T06:00:00.000"></event>
<event time="2019-02-02T06:00:00.000"></event>
</data>
当前transform.xsl
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<body>
<table>
<xsl:apply-templates select="/Adata/event|document('b.xml')/Bdata/event">
<xsl:sort select="@time"/>
</xsl:apply-templates>
</table>
</body>
</html>
</xsl:template>
<xsl:template match="Bdata/event">
<!--Here I have some long operation to change the date format and save it as parameter "correctFormat"-->
<xsl:attribute name="time">
<xsl:value-of select="$correctFormat"/>
</xsl:attribute>
</xsl:template>
<xsl:template match="//event">
<tr>
<td><xsl:value-of select="@time"/></td>
</tr>
</xsl:template>
</xsl:stylesheet>
预期输出out.html
<html>
<body>
<table>
<tr><td>2019-02-01T06:00:00.000</td></tr>
<tr><td>2019-02-02T06:00:00.000</td></tr>
<tr><td>2019-02-03T06:00:00.000</td></tr>
<tr><td>2019-02-04T06:00:00.000</td></tr>
</table>
</body>
</html>
编辑
日期转换码
根据要求,我也分享了我的转换代码。我通过在 header
中添加来使用 exslt 日期和时间命名空间
<xsl:template match="data/event">
<xsl:param name="daysToAdd" select="concat('P',substring(@time,6,3),'D')"/>
<xsl:param name="startOfYear" select="concat(substring(@time,1,4),'-01-00')"/>
<xsl:param name="formatedDate">
<xsl:call-template name="date:add">
<xsl:with-param name="date-time" select="$startOfYear" />
<xsl:with-param name="duration" select="$daysToAdd" />
</xsl:call-template>
<xsl:value-of select="substring(@time,9,13)"/>
</xsl:param>
<xsl:copy>
<xsl:attribute name="time">
<xsl:value-of select="$formatedDate"/>
</xsl:attribute>
</xsl:copy>
</xsl:template>
考虑以下示例(最小化为您问题中出现的问题):
XML
<data>
<event time="2019-02-03T06:00:00.000"></event>
<event time="2019-02-01T06:00:00.000"></event>
</data>
b.xml
<data>
<event time="2019-035T06:00:00.000"></event>
<event time="2019-033T06:00:00.000"></event>
</data>
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:strip-space elements="*"/>
<xsl:template match="/data">
<!-- CONVERT B -->
<xsl:variable name="b">
<xsl:for-each select="document('b.xml')/data/event">
<xsl:copy>
<xsl:attribute name="time">
<!-- the missing conversion part goes here -->
</xsl:attribute>
</xsl:copy>
</xsl:for-each>
</xsl:variable>
<!-- OUTPUT -->
<xsl:copy>
<xsl:for-each select="event | exsl:node-set($b)/event">
<xsl:sort select="@time" data-type="text" order="ascending"/>
<xsl:copy-of select="."/>
</xsl:for-each>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
结果
<?xml version="1.0" encoding="UTF-8"?>
<data>
<event time="2019-02-01T06:00:00.000"/>
<event time="2019-02-02T06:00:00.000"/>
<event time="2019-02-03T06:00:00.000"/>
<event time="2019-02-04T06:00:00.000"/>
</data>
我正在尝试使用 XSLT 1.0 将两个 XML 文件 "a.xml" 和 "b.xml" 合并到 HTML table 中。这两个文件都包含名为 "event" 的元素,每个元素都有一个 "time" 属性,并附加了一个 dateTime 值。我希望 HTML table 按时间顺序排序。文件 "a.xml" 的时间属性格式正确 (CCYY-MM-DDTHH:MM:SS.msmsms),而 "b.xml" 的时间属性格式不正确 (CCYY-DDDTHH:MM:SS.msmsmsZ),因此我正在使用一些连接和子字符串函数来为 "b.xml" 元素的 "time" 属性构造正确的格式。我现在的问题是:如何使用 "a.xml" 的原始 "time" 属性和 "b.xml" 的更正属性来对 HTML table 的行进行排序?
我已经尝试使用参数来存储格式正确的 "time" 属性。我还尝试使用节点集分两步解决问题(即首先转换 "b.xml" 属性,保存结果,然后从中间文件创建 HTML ),但这两种方法都不起作用我。最后,我尝试在页面加载时使用 JavaScript 对 HTML table 进行排序,但是 table 太大,无法在每次页面加载时以这种方式进行排序。
我很高兴 XSLT 功能的每一个提示都可以帮助我。不过,我必须坚持使用 XSLT1.0,不能将 XSLT2.0 用于该项目。
a.xml
<?xml version="1.0" encoding="UTF-8"?>
<data>
<event time="2019-02-03T06:00:00.000"></event>
<event time="2019-02-01T06:00:00.000"></event>
</data>
b.xml格式化前
<?xml version="1.0" encoding="UTF-8"?>
<data>
<event time="2019-035T06:00:00.000"></event>
<event time="2019-033T06:00:00.000"></event>
</data>
b.xml格式化后
<?xml version="1.0" encoding="UTF-8"?>
<data>
<event time="2019-02-04T06:00:00.000"></event>
<event time="2019-02-02T06:00:00.000"></event>
</data>
当前transform.xsl
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<body>
<table>
<xsl:apply-templates select="/Adata/event|document('b.xml')/Bdata/event">
<xsl:sort select="@time"/>
</xsl:apply-templates>
</table>
</body>
</html>
</xsl:template>
<xsl:template match="Bdata/event">
<!--Here I have some long operation to change the date format and save it as parameter "correctFormat"-->
<xsl:attribute name="time">
<xsl:value-of select="$correctFormat"/>
</xsl:attribute>
</xsl:template>
<xsl:template match="//event">
<tr>
<td><xsl:value-of select="@time"/></td>
</tr>
</xsl:template>
</xsl:stylesheet>
预期输出out.html
<html>
<body>
<table>
<tr><td>2019-02-01T06:00:00.000</td></tr>
<tr><td>2019-02-02T06:00:00.000</td></tr>
<tr><td>2019-02-03T06:00:00.000</td></tr>
<tr><td>2019-02-04T06:00:00.000</td></tr>
</table>
</body>
</html>
编辑
日期转换码
根据要求,我也分享了我的转换代码。我通过在 header
中添加来使用 exslt 日期和时间命名空间<xsl:template match="data/event">
<xsl:param name="daysToAdd" select="concat('P',substring(@time,6,3),'D')"/>
<xsl:param name="startOfYear" select="concat(substring(@time,1,4),'-01-00')"/>
<xsl:param name="formatedDate">
<xsl:call-template name="date:add">
<xsl:with-param name="date-time" select="$startOfYear" />
<xsl:with-param name="duration" select="$daysToAdd" />
</xsl:call-template>
<xsl:value-of select="substring(@time,9,13)"/>
</xsl:param>
<xsl:copy>
<xsl:attribute name="time">
<xsl:value-of select="$formatedDate"/>
</xsl:attribute>
</xsl:copy>
</xsl:template>
考虑以下示例(最小化为您问题中出现的问题):
XML
<data>
<event time="2019-02-03T06:00:00.000"></event>
<event time="2019-02-01T06:00:00.000"></event>
</data>
b.xml
<data>
<event time="2019-035T06:00:00.000"></event>
<event time="2019-033T06:00:00.000"></event>
</data>
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:strip-space elements="*"/>
<xsl:template match="/data">
<!-- CONVERT B -->
<xsl:variable name="b">
<xsl:for-each select="document('b.xml')/data/event">
<xsl:copy>
<xsl:attribute name="time">
<!-- the missing conversion part goes here -->
</xsl:attribute>
</xsl:copy>
</xsl:for-each>
</xsl:variable>
<!-- OUTPUT -->
<xsl:copy>
<xsl:for-each select="event | exsl:node-set($b)/event">
<xsl:sort select="@time" data-type="text" order="ascending"/>
<xsl:copy-of select="."/>
</xsl:for-each>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
结果
<?xml version="1.0" encoding="UTF-8"?>
<data>
<event time="2019-02-01T06:00:00.000"/>
<event time="2019-02-02T06:00:00.000"/>
<event time="2019-02-03T06:00:00.000"/>
<event time="2019-02-04T06:00:00.000"/>
</data>