Консолидация данных с использованием определенных ключей в XSLT - PullRequest
0 голосов
/ 22 февраля 2020

У меня есть входной файл XML:

<root>
   <row>
     <col1>cust001</col1>
     <col2>cc1</col2>
     <col3>po1</col3>
     <col4>2020-02-22</col4>
     <col5>Men</col5>
     <col6>item1</col6>
     <col7>60</col7>
   </row>
   <row>
     <col1>cust001</col1>
     <col2>cc1</col2>
     <col3>po1</col3>
     <col4>2020-02-22</col4>
     <col5>Men</col5>
     <col6>item2</col6>
     <col7>50</col7>
   </row>
</root> 

Желаемый вывод: (если столбцы от col1 до col5 совпадают, объединить в одну строку.)

<root>
       <row>
         <col1>cust001</col1>
         <col2>cc1</col2>
         <col3>po1</col3>
         <col4>2020-02-22</col4>
         <col5>Men</col5>
         <col6>item1</col6>
         <col7>60</col7>
         <col6>item2</col6>
         <col7>50</col7>
       </row>
    </root> 

I ' я пытаюсь код здесь XSLT Консолидация данных, когда идентификатор тот же , но я получаю, Ошибка в выражении current-group (): Неизвестная системная функция: текущая группа.

<xsl:stylesheet version="1.0" 
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns="http://www.castiron.com//response">

   <xsl:output method="xml" indent="yes"/>

   <xsl:template match="resultSets">
      <xsl:apply-templates select="@*|node()"/>
   </xsl:template>

   <xsl:template match="resultSet">
      <xsl:apply-templates select="@*"/>
      <xsl:for-each-group select="root/row" group-by="concat(col1,col2,col3,col4,col5)">            
            <xsl:value-of select="current-grouping-key()"/>
            <xsl:apply-templates select="current-group()" />            
      </xsl:for-each-group>
   </xsl:template>

1 Ответ

0 голосов
/ 22 февраля 2020

Если вы используете процессор XSLT 3, такой как Saxon 9.8 или более поздней версии или Altova XML 2017 R3 или более поздней версии, вы можете использовать составной ключ группировки элементов, которые вы хотите использовать в качестве ключа группировки, тогда, конечно, внутри вас необходимо убедиться, что вы создаете один row для каждой группы и обрабатываете элементы, образующие ключ группировки, только один раз (например, для первого элемента в группе, который является контекстным элементом внутри for-each-group), а затем для всех остальных элементы для всех элементов в группе:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="#all"
    version="3.0">

  <xsl:output indent="yes"/>

  <xsl:mode on-no-match="shallow-copy"/>

  <xsl:template match="root">
      <xsl:copy>
          <xsl:for-each-group select="row" composite="yes" group-by="col1, col2, col3, col4, col5">
              <xsl:copy>
                  <xsl:apply-templates select="col1, col2, col3, col4, col5, current-group()/(* except (col1, col2, col3, col4, col5))"/>
              </xsl:copy>
          </xsl:for-each-group>
      </xsl:copy>
  </xsl:template>

</xsl:stylesheet>

https://xsltfiddle.liberty-development.net/jz1Q1yt

Или, возможно, тело for-each-group немного менее повторяется в терминах ключевых элементов группировки с

  <xsl:template match="root">
    <xsl:copy>
        <xsl:for-each-group select="row!copy-of()" composite="yes" group-by="col1, col2, col3, col4, col5">
            <xsl:copy>
                <xsl:apply-templates select="current-group()/(if (position() eq 1) then * else (* except (col1, col2, col3, col4, col5)))"/>
            </xsl:copy>
        </xsl:for-each-group>
    </xsl:copy>
  </xsl:template>

https://xsltfiddle.liberty-development.net/jz1Q1yt/1

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...