XSLT 按员工编号、年、月、日、小时、分钟、秒对节点进行排序
XSLT sort node by employeeNumber, year, month, day, hour, minutes, seconds
我有一个 XML 并且想:
- 按员工编号排序,每个预订时间按年、月、日升序排列。
示例:
<?xml version="1.0" encoding="UTF-8"?>
<root>
<entry>
<employeeName>Bob the Builder</employeeName>
<employeeNumber>00290035</employeeNumber>
<requestCode>g</requestCode>
<bookingtime>
<year>2019</year>
<month>3</month>
<day>18</day>
<hours>14</hours>
<minutes>52</minutes>
<seconds>0</seconds>
</bookingtime>
</entry>
<entry>
<employeeName>Bob the Builder</employeeName>
<employeeNumber>00290035</employeeNumber>
<requestCode>c</requestCode>
<bookingtime>
<year>2019</year>
<month>3</month>
<day>18</day>
<hours>14</hours>
<minutes>22</minutes>
<seconds>0</seconds>
</bookingtime>
</entry>
<entry>
<employeeName>Mike Zeh</employeeName>
<employeeNumber>00200060</employeeNumber>
<requestCode>c</requestCode>
<bookingtime>
<year>2019</year>
<month>3</month>
<day>17</day>
<hours>10</hours>
<minutes>15</minutes>
<seconds>0</seconds>
</bookingtime>
</entry>
</root>
谁能帮我正确地做到这一点?使用的 XSLT 版本可以是任何版本,不需要特定版本。
我做了一个小的fiddle(https://xsltfiddle.liberty-development.net/ej9EGce),employeeNumber 排序成功,年份/月份等都失败了。
这个样式表
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="root">
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:apply-templates select="entry">
<xsl:sort select="employeeNumber" data-type="number"/>
<xsl:sort select="bookingtime/year" data-type="number"/>
<xsl:sort select="bookingtime/month" data-type="number"/>
<xsl:sort select="bookingtime/day" data-type="number"/>
<xsl:sort select="bookingtime/hours" data-type="number"/>
<xsl:sort select="bookingtime/minutes" data-type="number"/>
<xsl:sort select="bookingtime/seconds" data-type="number"/>
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
根据您的意见
<root>
<entry>
<employeeName>Bob the Builder</employeeName>
<employeeNumber>00290035</employeeNumber>
<requestCode>g</requestCode>
<bookingtime>
<year>2019</year>
<month>3</month>
<day>18</day>
<hours>14</hours>
<minutes>52</minutes>
<seconds>0</seconds>
</bookingtime>
</entry>
<entry>
<employeeName>Bob the Builder</employeeName>
<employeeNumber>00290035</employeeNumber>
<requestCode>c</requestCode>
<bookingtime>
<year>2018</year>
<month>3</month>
<day>18</day>
<hours>14</hours>
<minutes>22</minutes>
<seconds>0</seconds>
</bookingtime>
</entry>
<entry>
<employeeName>Mike Zeh</employeeName>
<employeeNumber>00200060</employeeNumber>
<requestCode>c</requestCode>
<bookingtime>
<year>2019</year>
<month>3</month>
<day>17</day>
<hours>10</hours>
<minutes>15</minutes>
<seconds>0</seconds>
</bookingtime>
</entry>
</root>
输出:
<root>
<entry>
<employeeName>Mike Zeh</employeeName>
<employeeNumber>00200060</employeeNumber>
<requestCode>c</requestCode>
<bookingtime>
<year>2019</year>
<month>3</month>
<day>17</day>
<hours>10</hours>
<minutes>15</minutes>
<seconds>0</seconds>
</bookingtime>
</entry>
<entry>
<employeeName>Bob the Builder</employeeName>
<employeeNumber>00290035</employeeNumber>
<requestCode>c</requestCode>
<bookingtime>
<year>2018</year>
<month>3</month>
<day>18</day>
<hours>14</hours>
<minutes>22</minutes>
<seconds>0</seconds>
</bookingtime>
</entry>
<entry>
<employeeName>Bob the Builder</employeeName>
<employeeNumber>00290035</employeeNumber>
<requestCode>g</requestCode>
<bookingtime>
<year>2019</year>
<month>3</month>
<day>18</day>
<hours>14</hours>
<minutes>52</minutes>
<seconds>0</seconds>
</bookingtime>
</entry>
</root>
请注意:如果您正在对 entry
元素进行排序,您可以使用每个 entry
的任何相对路径作为 xsl:sort
指令的 select
属性的上下文。这是 排序(输出每个 entry
)不同于分组(输出 disctint entry
并计算一些聚合)
我喜欢 Aljandro 的回答,但如果有人 坚持 使用更高版本的 XSLT 并将值真正视为 year, 月, 月日, 小时, 分钟 和 seconds,然后可以使用类似下面的东西,
此转换可能看起来有点复杂,但它将 的子项视为这些类型化对象的值,如果遇到无效的组件值,则会抛出错误 -- 例如 二月30日,月:13,小时:25,或分钟/ 秒61
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="root">
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:apply-templates select="entry">
<xsl:sort select="employeeNumber" data-type="number"/>
<xsl:sort select=
"xs:dateTime(concat(
string-join(
(
format-number(bookingtime/year, '0000'),
format-number(bookingtime/month, '00'),
format-number(bookingtime/day, '00')
), '-'
),
'T',
string-join(
(
format-number(bookingtime/hours, '00'),
format-number(bookingtime/minutes, '00'),
format-number(bookingtime/seconds, '00')
), ':'
)
)
)"/>
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
当此转换应用于提供的源 xml 文档时:
<root>
<entry>
<employeeName>Bob the Builder</employeeName>
<employeeNumber>00290035</employeeNumber>
<requestCode>g</requestCode>
<bookingtime>
<year>2019</year>
<month>3</month>
<day>18</day>
<hours>14</hours>
<minutes>52</minutes>
<seconds>0</seconds>
</bookingtime>
</entry>
<entry>
<employeeName>Bob the Builder</employeeName>
<employeeNumber>00290035</employeeNumber>
<requestCode>c</requestCode>
<bookingtime>
<year>2018</year>
<month>3</month>
<day>18</day>
<hours>14</hours>
<minutes>22</minutes>
<seconds>0</seconds>
</bookingtime>
</entry>
<entry>
<employeeName>Mike Zeh</employeeName>
<employeeNumber>00200060</employeeNumber>
<requestCode>c</requestCode>
<bookingtime>
<year>2019</year>
<month>3</month>
<day>17</day>
<hours>10</hours>
<minutes>15</minutes>
<seconds>0</seconds>
</bookingtime>
</entry>
</root>
产生了想要的、正确的结果:
<root>
<entry>
<employeeName>Mike Zeh</employeeName>
<employeeNumber>00200060</employeeNumber>
<requestCode>c</requestCode>
<bookingtime>
<year>2019</year>
<month>3</month>
<day>17</day>
<hours>10</hours>
<minutes>15</minutes>
<seconds>0</seconds>
</bookingtime>
</entry>
<entry>
<employeeName>Bob the Builder</employeeName>
<employeeNumber>00290035</employeeNumber>
<requestCode>c</requestCode>
<bookingtime>
<year>2018</year>
<month>3</month>
<day>18</day>
<hours>14</hours>
<minutes>22</minutes>
<seconds>0</seconds>
</bookingtime>
</entry>
<entry>
<employeeName>Bob the Builder</employeeName>
<employeeNumber>00290035</employeeNumber>
<requestCode>g</requestCode>
<bookingtime>
<year>2019</year>
<month>3</month>
<day>18</day>
<hours>14</hours>
<minutes>52</minutes>
<seconds>0</seconds>
</bookingtime>
</entry>
</root>
我有一个 XML 并且想:
- 按员工编号排序,每个预订时间按年、月、日升序排列。
示例:
<?xml version="1.0" encoding="UTF-8"?>
<root>
<entry>
<employeeName>Bob the Builder</employeeName>
<employeeNumber>00290035</employeeNumber>
<requestCode>g</requestCode>
<bookingtime>
<year>2019</year>
<month>3</month>
<day>18</day>
<hours>14</hours>
<minutes>52</minutes>
<seconds>0</seconds>
</bookingtime>
</entry>
<entry>
<employeeName>Bob the Builder</employeeName>
<employeeNumber>00290035</employeeNumber>
<requestCode>c</requestCode>
<bookingtime>
<year>2019</year>
<month>3</month>
<day>18</day>
<hours>14</hours>
<minutes>22</minutes>
<seconds>0</seconds>
</bookingtime>
</entry>
<entry>
<employeeName>Mike Zeh</employeeName>
<employeeNumber>00200060</employeeNumber>
<requestCode>c</requestCode>
<bookingtime>
<year>2019</year>
<month>3</month>
<day>17</day>
<hours>10</hours>
<minutes>15</minutes>
<seconds>0</seconds>
</bookingtime>
</entry>
</root>
谁能帮我正确地做到这一点?使用的 XSLT 版本可以是任何版本,不需要特定版本。
我做了一个小的fiddle(https://xsltfiddle.liberty-development.net/ej9EGce),employeeNumber 排序成功,年份/月份等都失败了。
这个样式表
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="root">
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:apply-templates select="entry">
<xsl:sort select="employeeNumber" data-type="number"/>
<xsl:sort select="bookingtime/year" data-type="number"/>
<xsl:sort select="bookingtime/month" data-type="number"/>
<xsl:sort select="bookingtime/day" data-type="number"/>
<xsl:sort select="bookingtime/hours" data-type="number"/>
<xsl:sort select="bookingtime/minutes" data-type="number"/>
<xsl:sort select="bookingtime/seconds" data-type="number"/>
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
根据您的意见
<root>
<entry>
<employeeName>Bob the Builder</employeeName>
<employeeNumber>00290035</employeeNumber>
<requestCode>g</requestCode>
<bookingtime>
<year>2019</year>
<month>3</month>
<day>18</day>
<hours>14</hours>
<minutes>52</minutes>
<seconds>0</seconds>
</bookingtime>
</entry>
<entry>
<employeeName>Bob the Builder</employeeName>
<employeeNumber>00290035</employeeNumber>
<requestCode>c</requestCode>
<bookingtime>
<year>2018</year>
<month>3</month>
<day>18</day>
<hours>14</hours>
<minutes>22</minutes>
<seconds>0</seconds>
</bookingtime>
</entry>
<entry>
<employeeName>Mike Zeh</employeeName>
<employeeNumber>00200060</employeeNumber>
<requestCode>c</requestCode>
<bookingtime>
<year>2019</year>
<month>3</month>
<day>17</day>
<hours>10</hours>
<minutes>15</minutes>
<seconds>0</seconds>
</bookingtime>
</entry>
</root>
输出:
<root>
<entry>
<employeeName>Mike Zeh</employeeName>
<employeeNumber>00200060</employeeNumber>
<requestCode>c</requestCode>
<bookingtime>
<year>2019</year>
<month>3</month>
<day>17</day>
<hours>10</hours>
<minutes>15</minutes>
<seconds>0</seconds>
</bookingtime>
</entry>
<entry>
<employeeName>Bob the Builder</employeeName>
<employeeNumber>00290035</employeeNumber>
<requestCode>c</requestCode>
<bookingtime>
<year>2018</year>
<month>3</month>
<day>18</day>
<hours>14</hours>
<minutes>22</minutes>
<seconds>0</seconds>
</bookingtime>
</entry>
<entry>
<employeeName>Bob the Builder</employeeName>
<employeeNumber>00290035</employeeNumber>
<requestCode>g</requestCode>
<bookingtime>
<year>2019</year>
<month>3</month>
<day>18</day>
<hours>14</hours>
<minutes>52</minutes>
<seconds>0</seconds>
</bookingtime>
</entry>
</root>
请注意:如果您正在对 entry
元素进行排序,您可以使用每个 entry
的任何相对路径作为 xsl:sort
指令的 select
属性的上下文。这是 排序(输出每个 entry
)不同于分组(输出 disctint entry
并计算一些聚合)
我喜欢 Aljandro 的回答,但如果有人 坚持 使用更高版本的 XSLT 并将值真正视为 year, 月, 月日, 小时, 分钟 和 seconds,然后可以使用类似下面的东西,
此转换可能看起来有点复杂,但它将
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="root">
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:apply-templates select="entry">
<xsl:sort select="employeeNumber" data-type="number"/>
<xsl:sort select=
"xs:dateTime(concat(
string-join(
(
format-number(bookingtime/year, '0000'),
format-number(bookingtime/month, '00'),
format-number(bookingtime/day, '00')
), '-'
),
'T',
string-join(
(
format-number(bookingtime/hours, '00'),
format-number(bookingtime/minutes, '00'),
format-number(bookingtime/seconds, '00')
), ':'
)
)
)"/>
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
当此转换应用于提供的源 xml 文档时:
<root>
<entry>
<employeeName>Bob the Builder</employeeName>
<employeeNumber>00290035</employeeNumber>
<requestCode>g</requestCode>
<bookingtime>
<year>2019</year>
<month>3</month>
<day>18</day>
<hours>14</hours>
<minutes>52</minutes>
<seconds>0</seconds>
</bookingtime>
</entry>
<entry>
<employeeName>Bob the Builder</employeeName>
<employeeNumber>00290035</employeeNumber>
<requestCode>c</requestCode>
<bookingtime>
<year>2018</year>
<month>3</month>
<day>18</day>
<hours>14</hours>
<minutes>22</minutes>
<seconds>0</seconds>
</bookingtime>
</entry>
<entry>
<employeeName>Mike Zeh</employeeName>
<employeeNumber>00200060</employeeNumber>
<requestCode>c</requestCode>
<bookingtime>
<year>2019</year>
<month>3</month>
<day>17</day>
<hours>10</hours>
<minutes>15</minutes>
<seconds>0</seconds>
</bookingtime>
</entry>
</root>
产生了想要的、正确的结果:
<root>
<entry>
<employeeName>Mike Zeh</employeeName>
<employeeNumber>00200060</employeeNumber>
<requestCode>c</requestCode>
<bookingtime>
<year>2019</year>
<month>3</month>
<day>17</day>
<hours>10</hours>
<minutes>15</minutes>
<seconds>0</seconds>
</bookingtime>
</entry>
<entry>
<employeeName>Bob the Builder</employeeName>
<employeeNumber>00290035</employeeNumber>
<requestCode>c</requestCode>
<bookingtime>
<year>2018</year>
<month>3</month>
<day>18</day>
<hours>14</hours>
<minutes>22</minutes>
<seconds>0</seconds>
</bookingtime>
</entry>
<entry>
<employeeName>Bob the Builder</employeeName>
<employeeNumber>00290035</employeeNumber>
<requestCode>g</requestCode>
<bookingtime>
<year>2019</year>
<month>3</month>
<day>18</day>
<hours>14</hours>
<minutes>52</minutes>
<seconds>0</seconds>
</bookingtime>
</entry>
</root>