Воспроизведение XML с атрибутами с использованием XSLT 2.0 и группировка одного элемента

Я новичок в XSLT, и мне пришлось сгруппировать/суммировать один элемент, поскольку у одного сотрудника может быть две строки данных. Я смог добиться этого, используя функцию tag и sum(current-group()). Входной xml имел атрибуты, и наряду с предыдущей необходимостью также необходимо было воспроизвести атрибуты xml в результирующем выходном xml.

**Sample XML:**
<ws:Review>
  <ws:Employee>
    <ws:EmpID>12345</ws:EmpID>
    <ws:Amount>4</ws:Amount>
    <ws:Amount>5</ws:Amount>
    <ws:Currency Descriptor="IDR">
      <ws:ID ws:type="AID">9464cef721784d6ab96eaad1b366f6e7</ws:ID>
      <ws:ID ws:type="Currency_ID">IDR</ws:ID>
    </ws:Currency>
  </ws:Employee>
  <ws:Employee>
    <ws:EmpID>12345</ws:EmpID>
    <ws:Amount>6</ws:Amount>
    <ws:Currency Descriptor="IDR">
      <ws:ID ws:type="AID">9464cef721784d6ab96eaad1b366f6e7</ws:ID>
      <ws:ID ws:type="Currency_ID">IDR</ws:ID>
    </ws:Currency>
  </ws:Employee>
  <ws:Employee>
    <ws:EmpID>23456</ws:EmpID>
    <ws:Amount>4</ws:Amount>
    <ws:Currency Descriptor="GBP">
      <ws:ID ws:type="AID">9464cef721784d6ab96eaad1b366f6e5</ws:ID>
      <ws:ID ws:type="Currency_ID">GBP</ws:ID>
    </ws:Currency>
  </ws:Employee>
  <ws:Employee>
    <ws:EmpID>34567</ws:EmpID>
    <ws:Amount>4</ws:Amount>
    <ws:Amount>5</ws:Amount>
    <ws:Currency Descriptor="USD">
      <ws:ID ws:type="AID">9464cef721784d6ab96eaad1b366f679</ws:ID>
      <ws:ID ws:type="Currency_ID">USD</ws:ID>
    </ws:Currency>
  </ws:Employee>
</ws:Review>

Ожидаемый результат:

<ws:Review>
  <ws:Employee>
    <ws:EmpID>12345</ws:EmpID>
    <ws:Amount>15</ws:Amount>
    <ws:Currency Descriptor="IDR">
      <ws:ID ws:type="AID">9464cef721784d6ab96eaad1b366f6e7</ws:ID>
      <ws:ID ws:type="Currency_ID">IDR</ws:ID>
    </ws:Currency>
  </ws:Employee>
  <ws:Employee>
    <ws:EmpID>23456</ws:EmpID>
    <ws:Amount>4</ws:Amount>
    <ws:Currency Descriptor="GBP">
      <ws:ID ws:type="AID">9464cef721784d6ab96eaad1b366f6e7</ws:ID>
      <ws:ID ws:type="Currency_ID">GBP</ws:ID>
    </ws:Currency>
  </ws:Employee>
  <ws:Employee>
    <ws:EmpID>34567</ws:EmpID>
    <ws:Amount>9</ws:Amount>
    <ws:Currency Descriptor="USD">
      <ws:ID ws:type="AID">9464cef721784d6ab96eaad1b366f6e7</ws:ID>
      <ws:ID ws:type="Currency_ID">USD</ws:ID>
    </ws:Currency>
  </ws:Employee>
</ws:Review>

XSL, который я написал:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ws="namespace" version="2.0">

<xsl:output method="xml" encoding="UTF-8" indent="yes"/>

<xsl:template match="/">
  <ws:Review>
    <xsl:for-each-group select="ws:Review/ws:Employee" group-by="ws:Employee/ws:EmpID>
      <ws:EmpID><xsl:value-of select="ws:Employee/ws:EmpID"/></ws:EmpID>
      <ws:Currency><xsl:value-of select="ws:Employee/ws:Currency/@ws:Descriptor"/></ws:Currency>
      <ws:Amount><xsl:value-of select="sum(current-group()/ws:Employee/ws:Amount)"/></ws:Amount>
    </xsl:for-each-group>
  </ws:Review>
</xsl:template>

Может ли кто-нибудь помочь мне изменить текущий xsl таким образом, чтобы атрибуты переносились вперед? Буду рад любой оказанной помощи.

Спасибо! Вивек


person Vivek    schedule 15.05.2015    source источник


Ответы (1)


Я бы подтолкнул элементы к преобразованию личности, см. http://xsltransform.net/bdxtqy, что делает

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0" xmlns:ws="http://example.com/">

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


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

    <xsl:template match="ws:Review">
        <xsl:copy>
            <xsl:for-each-group select="ws:Employee" group-by="ws:EmpID">
                <xsl:copy>
                    <xsl:apply-templates select="ws:EmpID"/>
                    <ws:Amount><xsl:value-of select="sum(current-group()/ws:Amount)"/></ws:Amount>
                    <xsl:apply-templates select="* except (ws:EmpID, ws:Amount)"/>
                </xsl:copy>
            </xsl:for-each-group>
        </xsl:copy>
    </xsl:template>
</xsl:transform>
person Martin Honnen    schedule 15.05.2015
comment
Мартин, большое спасибо. Работал отлично и ценю вашу помощь! - person Vivek; 16.05.2015