You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用XSLT合并XML元素并重构同名同类型的元素/属性?

基于XSLT合并同ATTRIBUTEX值的ELEMENT元素

需求回顾

输入XML示例:

<FILE>
  <ELEMENT>
    <ATTRIBUTEX>1</ATTRIBUTEX>
    <ATTRIBUTEY>A</ATTRIBUTEY>
  </ELEMENT>
  <ELEMENT>
    <ATTRIBUTEX>1</ATTRIBUTEX>
    <ATTRIBUTEY>B</ATTRIBUTEY>
  </ELEMENT>
</FILE>

期望输出:

<FILE>
  <ELEMENT>
    <ATTRIBUTEX>1</ATTRIBUTEX>
    <NEWELEMENT>
      <ATTRIBUTEY>A</ATTRIBUTEY>
    </NEWELEMENT>
    <NEWELEMENT>
      <ATTRIBUTEY>B</ATTRIBUTEY>
    </NEWELEMENT>
  </ELEMENT>
</FILE>

XSLT 1.0 解决方案(Muenchian分组)

XSLT 1.0中可以用Muenchian分组直接完成分组与结构重构,无需提前合并元素:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <!-- 定义分组键:按ATTRIBUTEX的文本值分组 -->
  <xsl:key name="elementByX" match="ELEMENT" use="ATTRIBUTEX/text()" />

  <xsl:template match="FILE">
    <FILE>
      <!-- 遍历每个唯一分组的第一个ELEMENT(代表该组) -->
      <xsl:for-each select="ELEMENT[count(. | key('elementByX', ATTRIBUTEX/text())[1]) = 1]">
        <ELEMENT>
          <!-- 复制当前组的ATTRIBUTEX -->
          <xsl:copy-of select="ATTRIBUTEX" />
          <!-- 遍历当前组内的所有ELEMENT,生成对应的NEWELEMENT -->
          <xsl:for-each select="key('elementByX', ATTRIBUTEX/text())">
            <NEWELEMENT>
              <xsl:copy-of select="ATTRIBUTEY" />
            </NEWELEMENT>
          </xsl:for-each>
        </ELEMENT>
      </xsl:for-each>
    </FILE>
  </xsl:template>
</xsl:stylesheet>

代码说明

  1. <xsl:key>:定义分组规则,将所有ELEMENT按ATTRIBUTEX的文本值分组。
  2. 外层xsl:for-each:筛选出每个分组的第一个ELEMENT,确保每个ATTRIBUTEX值只生成一个父ELEMENT。
  3. 内层xsl:for-each:遍历当前分组下的所有ELEMENT,为每个ATTRIBUTEY生成独立的NEWELEMENT。

XSLT 2.0+ 简化解决方案

如果使用XSLT 2.0或更高版本,可直接用for-each-group语法,代码更简洁:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="FILE">
    <FILE>
      <!-- 按ATTRIBUTEX的值分组 -->
      <xsl:for-each-group select="ELEMENT" group-by="ATTRIBUTEX">
        <ELEMENT>
          <xsl:copy-of select="current-group()[1]/ATTRIBUTEX" />
          <!-- 遍历分组内的每个元素,生成NEWELEMENT -->
          <xsl:for-each select="current-group()">
            <NEWELEMENT>
              <xsl:copy-of select="ATTRIBUTEY" />
            </NEWELEMENT>
          </xsl:for-each>
        </ELEMENT>
      </xsl:for-each-group>
    </FILE>
  </xsl:template>
</xsl:stylesheet>

原有方案错误原因

你之前的代码存在两个核心问题:

  1. 硬编码NEWELEMENT数量:手动写了两个NEWELEMENT,无法适配任意数量的ATTRIBUTEY。
  2. 未遍历单个ATTRIBUTEY:xsl:copy-of select="ATTRIBUTEY"会选中当前ELEMENT下所有ATTRIBUTEY元素,导致每个NEWELEMENT都包含所有值。

通过XSLT分组可以直接从原始XML完成合并与结构重构,无需提前合并元素,避免了同名元素带来的处理问题。

内容的提问来源于stack exchange,提问作者Benjamin Hammond

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 08:35:33