XML - 使用 XSLT 合并同一节点多次出现的子元素

Posted

技术标签:

【中文标题】XML - 使用 XSLT 合并同一节点多次出现的子元素【英文标题】:XML - Merging child elements of multiple occurrences of the same node using XSLT 【发布时间】:2022-01-08 15:46:16 【问题描述】:

我有以下由外部系统发送的源文件。

<?xml version="1.0" encoding="utf-8"?>
<root>
  <remoteId>id-sent-by-sender</remoteId>
  <payments>
    <payment>
      <amount>383700</amount>
      <remoteId>unique-id-1</remoteId>
      <beneficiary>
        <accountNumber>CustomerAccount_1</accountNumber>
        <country>fr</country>
        <routingNumber>AAABBBBCCC</routingNumber>
        <title>Dale's Shop</title>
        <email>dale@shop.com</email>
      </beneficiary>
      <feeBearer>
        <party>supplier</party>
        <supplierFeePercent>1.00</supplierFeePercent>
      </feeBearer>
      <currency>eur</currency>
      <dateDue>2021-07-21</dateDue>
      <metaData>
        <data>
          <key>a-key</key>
          <value>a value</value>
        </data>
        <data>
          <key>another-key</key>
          <value>another value</value>
        </data>
      </metaData>
      <reference>
        <row>invoice row 1</row>
      </reference>
      <reference>
        <row>invoice row 2</row>
      </reference>
      <reference>
        <row>invoice row 3</row>
      </reference>
    </payment>
    <payment>
      <amount>100000</amount>
      <remoteId>unique-id-2</remoteId>
      <beneficiary>
        <accountNumber>CustomerAccount_2</accountNumber>
        <country>gb</country>
        <routingNumber>BBBKKKKSSS</routingNumber>
        <title>Ramos Tacos</title>
      </beneficiary>
      <feeBearer>
        <party>supplier</party>
        <supplierFeePercent>1.00</supplierFeePercent>
      </feeBearer>
      <currency>eur</currency>
      <reference>
        <row>invoice row 1</row>
      </reference>
      <reference>
        <row>invoice row 2</row>
      </reference>
      <reference>
        <row>invoice row 3</row>
      </reference>
    </payment>
  </payments>
</root>

我需要将文件更改为如下所示。

<?xml version="1.0" encoding="utf-8"?>
<root>
  <remoteId>id-send-by-sender</remoteId>
  <payments>
    <payment>
      <amount>383700</amount>
      <remoteId>unique-id-1</remoteId>
      <beneficiary>
        <accountNumber>CustomerAccount_1</accountNumber>
        <country>fr</country>
        <routingNumber>AAABBBBCCC</routingNumber>
        <title>Dale's Shop</title>
        <email>dale@shop.com</email>
      </beneficiary>
      <feeBearer>
        <party>supplier</party>
        <supplierFeePercent>1.00</supplierFeePercent>
      </feeBearer>
      <currency>eur</currency>
      <dateDue>2021-07-21</dateDue>
      <metaData>
        <data>
          <key>a-key</key>
          <value>a value</value>
        </data>
        <data>
          <key>another-key</key>
          <value>another value</value>
        </data>
      </metaData>
      <reference>
        <row>invoice row 1</row>
        <row>invoice row 2</row>
        <row>invoice row 3</row>
      </reference>
    </payment>
    <payment>
      <amount>100000</amount>
      <beneficiary>
        <accountNumber>CustomerAccount_2</accountNumber>
        <country>gb</country>
        <routingNumber>BBBKKKKSSS</routingNumber>
        <title>Ramos Tacos</title>
      </beneficiary>
      <feeBearer>
        <party>supplier</party>
        <supplierFeePercent>1.00</supplierFeePercent>
      </feeBearer>
      <currency>eur</currency>
      <reference>
        <row>invoice row 1</row>
        <row>invoice row 2</row>
        <row>invoice row 3</row>
      </reference>
      <remoteId>unique-id-2</remoteId>
    </payment>
  </payments>
</root>

简而言之,这 2 个 XML 之间的区别在于,第一个 XML 有不止一次出现的元素 &lt;reference&gt;,我需要将其合并为一个出现,同时保持所有这些出现的子元素不变。

这可以使用 XSLT 完成吗?如果是,有人可以帮忙吗? 我在这方面很新手,当我搜索帖子时,不明白如何去做。

谢谢

【问题讨论】:

请就您在尝试完成此操作时遇到的困难提出一个具体问题。否则,看起来您只是在寻找某人为您编写代码。 --附言这是一项微不足道的任务;花一个小时或更少的时间学习 XSLT 教程,你就会知道如何做。 【参考方案1】:

我希望看到包含标准身份模板的样式表以及规则:

<xsl:template match="payment">
  <xsl:copy>
    <xsl:apply-templates/>
    <reference>
      <xsl:copy-of select="reference/row"/>
    </reference>
  </xsl:copy>
</xsl:template>

<xsl:template match="reference"/>

【讨论】:

以上是关于XML - 使用 XSLT 合并同一节点多次出现的子元素的主要内容,如果未能解决你的问题,请参考以下文章

使用 XSLT 将具有相同 ID 的元素 (XML) 合并到 txt 文件

XSLT 分组/合并子项(使用密钥)

XSLT将同名兄弟节点的值合并/连接到单个节点中

使用 XSLT 基于 ID 从多个 xPath 中选择 XML 节点

使用 XSLT 枚举同名节点

将 xml 中的节点与 xslt 进行比较