XSLT按employeeNumber,年,月,日,时,分,秒排序的节点

时间:2019-03-22 12:09:25

标签: xslt xslt-1.0 xslt-2.0 xslt-3.0

我有一个XML,并且想要:

  • 按employeeNumber排序,并且每个预订时间按年,月,日递增。

示例:

<?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版本可以是任何版本,不需要特定的版本。

我做了一个小提琴(https://xsltfiddle.liberty-development.net/ej9EGce),employeeNumber的排序工作,年/月等都失败了。

2 个答案:

答案 0 :(得分:0)

此样式表

<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的任何相对路径用作select指令的xsl:sort属性的上下文。 排序(每个entry输出)与分组(输出离散entry并计算一些聚合)不同

答案 1 :(得分:0)

我喜欢Aljandro的答案,但是如果有人坚持使用更高版本的XSLT并将其值确实视为 year month em>,每月小时分钟,则可以使用以下类似的内容,

此转换可能看起来有些复杂,但会将的子代视为这些类型对象的值,如果遇到无效的组件值(例如 Feb ),则会引发错误。 em> 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>