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

如何用XSLT 1.0合并XML中跨message的同ID object元素?

用XSLT 1.0合并两个message中的同ID object元素并整合内容

我查了很多XSLT合并与分组的文章,但没找到匹配我场景的案例。作为偶尔开发的人,我觉得XSLT的合并/分组操作挺复杂,尤其是嵌套XML里有多个"数组"的情况。有一篇类似的文章《XML merge nodes with XSLT》,但它是在单一场景内分组,不是跨不同场景分组。

我的需求:
合并根节点为messages的XML文件中的两个message元素(固定两个)。合并后的message里,需要基于object元素的ID进行合并,只保留ID在两个message中都存在的object,并整合它们的所有子元素。

初始XML

<?xml version="1.0" encoding="UTF-8"?>
<messages>
    <message>
        <submessage>
            <object>
                <ID>991</ID>
                <Extra>ABC</Extra>
            </object>
            <object>
                <ID>992</ID>
                <Extra>BCD</Extra>
            </object>
            <object>
                <ID>993</ID>
                <Extra>CDE</Extra>
            </object>
        </submessage>
    </message>
    <message>
        <submessage>
            <object>
                <ID>992</ID>
                <Name>Marcel</Name>
                <Description>XXX</Description>
            </object>
            <object>
                <ID>993</ID>
                <Name>Peter</Name>
                <Description>YYY</Description>
            </object>
            <object>
                <ID>994</ID>
                <Name>Lola</Name>
                <Description>ZZZ</Description>
            </object>
        </submessage>
    </message>
</messages>

期望结果XML

<?xml version="1.0" encoding="UTF-8"?>
<messages>
    <message>
        <submessage>
            <object>
                <ID>992</ID>
                <Name>Marcel</Name>
                <Description>XXX</Description>
                <Extra>BCD</Extra>
            </object>
            <object>
                <ID>993</ID>
                <Name>Peter</Name>
                <Description>YYY</Description>
                <Extra>CDE</Extra>
            </object>
        </submessage>
    </message>
</messages>

说明:仅保留两个message中ID匹配的object元素,比如ID为991和994的object会被删除,ID为992和993的object会被保留并整合所有内部元素。每个message下仅存在一个submessage元素。


XSLT 1.0解决方案

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <!-- 按ID分组所有object元素 -->
    <xsl:key name="object-by-id" match="object" use="ID"/>

    <!-- 匹配根节点messages -->
    <xsl:template match="/messages">
        <messages>
            <message>
                <submessage>
                    <!-- 筛选出在两个message中都存在的object分组(分组大小为2) -->
                    <xsl:for-each select="message/submessage/object[count(key('object-by-id', ID)) = 2][generate-id() = generate-id(key('object-by-id', ID)[1])]">
                        <object>
                            <!-- 复制当前分组下所有object的子元素 -->
                            <xsl:copy-of select="key('object-by-id', ID)/*"/>
                        </object>
                    </xsl:for-each>
                </submessage>
            </message>
        </messages>
    </xsl:template>
</xsl:stylesheet>

代码说明

  1. Muenchian分组:通过<xsl:key>定义按ID分组所有object元素,这是XSLT 1.0中实现高效分组的标准方法。
  2. 筛选匹配ID:使用count(key('object-by-id', ID)) = 2确保只保留在两个message中都存在的object(因为每个匹配的ID恰好对应两个object节点,分别来自两个message)。
  3. 去重分组:generate-id() = generate-id(key('object-by-id', ID)[1])确保每个ID只处理一次,避免重复创建object节点。
  4. 整合子元素:通过<xsl:copy-of select="key('object-by-id', ID)/*"将同一ID下所有object的子元素复制到新的object节点中,实现内容整合。

内容的提问来源于stack exchange,提问作者Robin Haes

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 03:44:58