Объединить две записи в одну запись в xslt

Запрос

<Records>
        <Record>
            <ACCOUNT>460029</ACCOUNT>
            <ENTITY>1851</ENTITY>
            <UD1>FY17</UD1>
            <UD2>457001</UD2>
            <UD3>116029</UD3>
            <UD4>0</UD4>
            <UD5>458004</UD5>
            <UD6>Dec</UD6>
            <UD7>DeferredIncome</UD7>
            <AMOUNT>0</AMOUNT>
        </Record>
        <Record>
            <ACCOUNT>460029</ACCOUNT>
            <ENTITY>1851</ENTITY>
            <UD1>FY17</UD1>
            <UD2>457001</UD2>
            <UD3>116029</UD3>
            <UD4>0</UD4>
            <UD5>458004</UD5>
            <UD6>Dec</UD6>
            <UD7>OutsBalance</UD7>
            <AMOUNT>3400</AMOUNT>
        </Record>
        <Record>
            <ACCOUNT>460029</ACCOUNT>
            <ENTITY>1851</ENTITY>
            <UD1>FY17</UD1>
            <UD2>457002</UD2>
            <UD3>116029</UD3>
            <UD4>0</UD4>
            <UD5>458008</UD5>
            <UD6>Jan</UD6>
            <UD7>DeferredIncome</UD7>
            <AMOUNT>20</AMOUNT>
        </Record>
        <Record>
            <ACCOUNT>460029</ACCOUNT>
            <ENTITY>1851</ENTITY>
            <UD1>FY17</UD1>
            <UD2>457002</UD2>
            <UD3>116029</UD3>
            <UD4>0</UD4>
            <UD5>458008</UD5>
            <UD6>Jan</UD6>
            <UD7>OtsBalance</UD7>
            <AMOUNT>0</AMOUNT>
        </Record>
    </Records>

отклик

  <Records>
            <Record>
                <ACCOUNT>460029</ACCOUNT>
                <ENTITY>1851</ENTITY>
                <UD1>FY17</UD1>
                <UD2>457001</UD2>
                <UD3>116029</UD3>
                <UD4>0</UD4>
                <UD5>458004</UD5>
                <UD6>Dec</UD6>
                <DeferredIncome>0</DeferredIncome>
                <OutsBalance>3400</OutsBalance>
            </Record>
            <Record>
                <ACCOUNT>460029</ACCOUNT>
                <ENTITY>1851</ENTITY>
                <UD1>FY17</UD1>
                <UD2>457002</UD2>
                <UD3>116029</UD3>
                <UD4>0</UD4>
                <UD5>458008</UD5>
                <UD6>Jan</UD6>
                <DeferredIncome>20</DeferredIncome>
                <OutsBalance>0</OutsBalance>
            </Record>
        </Records>
<br/>

У меня есть требование, когда мне нужно объединить две записи в одну в xslt.
. Будет более 1000 записей, поэтому выполнение для каждого внутри для каждого увеличит количество итераций. Есть ли лучший способ сделать это? Любая помощь приветствуется. Обычно каждая уникальная запись (от Amount до UD7) будет иметь две записи deffredAmount и outBalance. Необходимо объединить эти два рекорда с помощью defferedAmount и outBalance.

Можете ли вы показать нам несколько минимальных, но полных примеров кода XML для ввода и желаемого вывода вместе с объяснением значений, которые вы хотите использовать для объединения ваших данных? Вы можете сгруппировать две последовательности, например, xsl:for-each-group select="foo, bar" group-by="account" в XSLT 2.

Martin Honnen 13.09.2018 18:34

@MartinHonnen я добавил reqq и resp xml в соответствии с вашим req

user1643763 13.09.2018 21:17

Я не уверен, что понимаю из этих двух примеров, какие данные вы хотите использовать для слияния или объединения элементов Record, это несколько дочерних элементов («от количества до UD7», кажется, предполагает это)? Можете ли вы использовать XSLT 3 (например, с Saxon 9.8) вместо XSLT 2, поскольку XSLT 3 позволяет использовать composite="yes" на for-each-group group-by="ACCOUNT, ENTITY, UD1, UD2", и это упростило бы решение этой группировки?

Martin Honnen 13.09.2018 22:22
0
3
31
1

Ответы 1

Как я уже предлагал в комментарии, это похоже на случай из учебника для использования новой функции XSLT 3 for-each-group group-by composite="yes", то есть для использования последовательности элементов, которые вы хотите использовать в качестве ключей группировки для выражения group-by, и для указания с помощью composite="yes" что все они образуют составной ключ для группировки элементов.

Итак, для вашего примера с кодом XSLT 3

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="#all"
    expand-text="yes"
    version="3.0">

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

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

  <xsl:template match="Records">
      <xsl:copy>
          <xsl:for-each-group select="Record" group-by="*[position() le 8]" composite="yes">
              <xsl:copy>
                  <xsl:apply-templates select="* except (UD7, AMOUNT)"/>
                  <DeferredIncome>{ sum(current-group()[UD7 = 'DeferredIncome']/AMOUNT) }</DeferredIncome>
                  <OutsBalance>{ sum(current-group()[UD7 = ('OtsBalance', 'OutsBalance')]/AMOUNT) }</OutsBalance>
              </xsl:copy>
          </xsl:for-each-group>
      </xsl:copy>
  </xsl:template>

</xsl:stylesheet>

которые на выходах https://xsltfiddle.liberty-development.net/bdxtqC

<?xml version="1.0" encoding="UTF-8"?>
<Records>
   <Record>
      <ACCOUNT>460029</ACCOUNT>
      <ENTITY>1851</ENTITY>
      <UD1>FY17</UD1>
      <UD2>457001</UD2>
      <UD3>116029</UD3>
      <UD4>0</UD4>
      <UD5>458004</UD5>
      <UD6>Dec</UD6>
      <DeferredIncome>0</DeferredIncome>
      <OutsBalance>3400</OutsBalance>
   </Record>
   <Record>
      <ACCOUNT>460029</ACCOUNT>
      <ENTITY>1851</ENTITY>
      <UD1>FY17</UD1>
      <UD2>457002</UD2>
      <UD3>116029</UD3>
      <UD4>0</UD4>
      <UD5>458008</UD5>
      <UD6>Jan</UD6>
      <DeferredIncome>20</DeferredIncome>
      <OutsBalance>0</OutsBalance>
   </Record>
</Records>

Я не уверен, была ли необходима проверка UD7 = ('OtsBalance', 'OutsBalance') из-за опечаток в ваших выборочных данных или это необходимо вашим реальным данным, потому что они содержат разные варианты написания этого значения элемента.

Другие вопросы по теме