Как разрешить Группировать и Сортировать с помощью XSLT - PullRequest
0 голосов
/ 17 апреля 2019

У меня есть следующее входное сообщение, где данные должны быть сгруппированы на основе «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 голосов
/ 18 апреля 2019

На основании вашего описания я думаю, что вы хотите

<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>

Я не уверен, из какого элемента в группе вы хотите взять не сгруппированные дочерние элементы.

...