如何使用XSLT解决分组和排序

时间:2019-04-17 10:28:01

标签: xslt xslt-2.0 xslt-grouping

我有以下输入消息,其中需要首先基于“ EmpNo”和“ Date”对数据进行分组。但结果应取自“ lastDateTime”字段的最新日期时间

输入XML:

<Record>
<Record>
  <Date>2019-04-01T00:00:00.000</Date>
  <Hours>3</Hours>
  <EmpNo>825</EmpNo>
  <lastDateTime>2019-04-12T08:35:38.000</lastDateTime>
  <Rate>1139</Rate>
  <Code>102486</Code>
</Record>
<Record>
  <Date>2019-04-01T00:00:00.000</Date>
  <Hours>4</Hours>
  <EmpNo>826</EmpNo>
  <lastDateTime>2019-04-12T08:35:38.000</lastDateTime>
  <Rate>1139</Rate>
  <Code>102486</Code>
</Record>
<Record>
  <Date>2019-04-01T00:00:00.000</Date>
  <Hours>5</Hours>
  <EmpNo>827</EmpNo>
  <lastDateTime>2019-04-12T08:35:38.000</lastDateTime>
  <Rate>1139</Rate>
  <Code>102486</Code>
</Record>
<Record>
  <Date>2019-04-01T00:00:00.000</Date>
  <Hours>3</Hours>
  <EmpNo>825</EmpNo>
  <lastDateTime>2019-04-14T08:35:38.000</lastDateTime>
  <Rate>1139</Rate>
  <Code>102486</Code>
</Record>
<Record>
  <Date>2019-04-01T00:00:00.000</Date>
  <Hours>4</Hours>
  <EmpNo>826</EmpNo>
  <lastDateTime>2019-04-10T08:35:38.000</lastDateTime>
  <Rate>1139</Rate>
  <Code>102486</Code>
</Record>
<Record>
  <Date>2019-04-01T00:00:00.000</Date>
  <Hours>5</Hours>
  <EmpNo>827</EmpNo>
  <lastDateTime>2019-04-12T08:35:38.000</lastDateTime>
  <Rate>1139</Rate>
  <Code>102486</Code>
</Record>
<Record>
  <Date>2019-04-01T00:00:00.000</Date>
  <Hours>3</Hours>
  <EmpNo>825</EmpNo>
  <lastDateTime>2019-04-10T08:35:38.000</lastDateTime>
  <Rate>1139</Rate>
  <Code>102486</Code>
</Record>
<Record>
  <Date>2019-04-01T00:00:00.000</Date>
  <Hours>4</Hours>
  <EmpNo>826</EmpNo>
  <lastDateTime>2019-04-11T08:35:38.000</lastDateTime>
  <Rate>1139</Rate>
  <Code>102486</Code>
</Record>
<Record>
  <Date>2019-04-01T00:00:00.000</Date>
  <Hours>5</Hours>
  <EmpNo>827</EmpNo>
  <lastDateTime>2019-04-16T08:35:38.000</lastDateTime>
  <Rate>1139</Rate>
  <Code>102486</Code>
</Record>
</Record>

在输入XML文件中也可能有许多带有不同日期的EmpNo。需要将其分组,但是只需要提取lastDateTime是最新的那个特定节点。

预期结果:

<Record>
<Record>
  <Date>2019-04-01T00:00:00.000</Date>
  <Hours>6</Hours>
  <EmpNo>825</EmpNo>
  <lastDateTime>2019-04-14T08:35:38.000</lastDateTime>
  <Rate>1142</Rate>
  <Code>13</Code>
</Record>
<Record>
  <Date>2019-04-01T00:00:00.000</Date>
  <Hours>4</Hours>
  <EmpNo>826</EmpNo>
  <lastDateTime>2019-04-12T08:35:38.000</lastDateTime>
  <Rate>1140</Rate>
  <Code>11</Code>
</Record>
<Record>
  <Date>2019-04-01T00:00:00.000</Date>
  <Hours>11</Hours>
  <EmpNo>827</EmpNo>
  <lastDateTime>2019-04-16T08:35:38.000</lastDateTime>
  <Rate>1147</Rate>
  <Code>18</Code>
</Record>
</Record>

我试图编写以下代码,但是没有运气。

<?xml version="1.0" encoding="UTF-8"?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:mf="http://example.com/mf"    exclude-result-prefixes="#all" version="2.0">

<xsl:output method="xml" encoding="utf-8" indent="no"/>
<xsl:template match="Record">
<xsl:copy>
    <xsl:for-each-group select="Record" group-by="EmpNo">
        <xsl:for-each-group select="current-group()" group-by="Date">
            <xsl:copy>
                <EmpNo>
                    <xsl:value-of select="EmpNo"/>
                </EmpNo>
                <Date>
                    <xsl:value-of select="Date"/>
                </Date>
                <lastDateTime>
                    <xsl:value-of select="max(current-group()/lastDateTime/xs:dateTime(.))"/>
                </lastDateTime>
                <Hours>
                    <xsl:value-of select="Hours[Date=max(current-group()/lastDateTime/xs:dateTime(.))]"/>
                </Hours>                
            </xsl:copy>
        </xsl:for-each-group>
    </xsl:for-each-group>
</xsl:copy>
</xsl:template>
</xsl:transform>

1 个答案:

答案 0 :(得分:0)

根据您的描述,我认为您想要

<xsl:template match="Record">
<xsl:copy>
    <xsl:for-each-group select="Record" group-by="EmpNo">
        <xsl:for-each-group select="current-group()" group-by="Date">
            <xsl:for-each select="current-group()">
                <xsl:sort select="xs:dateTime(lastDateTime)"/>
                <xsl:if test="position() = last()">
                    <xsl:copy-of select="."/>
                </xsl:if>
            </xsl:for-each>
        </xsl:for-each-group>
    </xsl:for-each-group>
</xsl:copy>
</xsl:template>

但是,在https://xsltfiddle.liberty-development.net/ncdD7mB处的结果是

<Record>
   <Record>
      <Date>2019-04-01T00:00:00.000</Date>
      <Hours>3</Hours>
      <EmpNo>825</EmpNo>
      <lastDateTime>2019-04-14T08:35:38.000</lastDateTime>
      <Rate>1139</Rate>
      <Code>102486</Code>
   </Record>
   <Record>
      <Date>2019-04-01T00:00:00.000</Date>
      <Hours>4</Hours>
      <EmpNo>826</EmpNo>
      <lastDateTime>2019-04-12T08:35:38.000</lastDateTime>
      <Rate>1139</Rate>
      <Code>102486</Code>
   </Record>
   <Record>
      <Date>2019-04-01T00:00:00.000</Date>
      <Hours>5</Hours>
      <EmpNo>827</EmpNo>
      <lastDateTime>2019-04-16T08:35:38.000</lastDateTime>
      <Rate>1139</Rate>
      <Code>102486</Code>
   </Record>
</Record>

我不确定要从组中的哪个项目中获取未分组的子元素。