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

xsltproc合并XML文件异常:丢失新文件节点求助

解决XML合并时丢失新文件节点的问题

你的问题出在当前的XSLT逻辑上:当匹配Item节点时,只有找到abc.xml中对应measurement的匹配项才会输出,完全忽略了xyz.xml中没有匹配的Item,同时也没有把abc.xml中独有的Item添加进去。

我们需要调整XSLT逻辑,实现三个核心目标:

  • 保留xyz.xml中所有的Item:如果在abc.xml找到相同measurement的Item,就用abc的替换;否则保留原xyz的Item
  • 把abc.xml中xyz.xml没有的Item补充到结果里
  • 保持原有的节点复制逻辑(identity template)

以下是修改后的logic.xslt:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" version="1.0" encoding="UTF-8" standalone="no" indent="yes"/>
    
    <!-- 定义key,方便快速查找abc.xml中按measurement匹配的Item -->
    <xsl:key name="abc-item-by-measurement" match="/schedule/Item" use="measurements/measurement"/>
    
    <!-- 基础的identity模板,复制所有未被特殊处理的节点 -->
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()" />
        </xsl:copy>
    </xsl:template>
    
    <!-- 处理xyz.xml中的Item节点 -->
    <xsl:template match="Item">
        <!-- 查找abc.xml中对应measurement的Item -->
        <xsl:variable name="matching-abc-item" select="key('abc-item-by-measurement', measurements/measurement, document('./abc.xml'))"/>
        <!-- 如果找到匹配项,输出abc的Item;否则保留当前xyz的Item -->
        <xsl:choose>
            <xsl:when test="$matching-abc-item">
                <xsl:copy-of select="$matching-abc-item"/>
            </xsl:when>
            <xsl:otherwise>
                <xsl:copy>
                    <xsl:apply-templates select="@*|node()"/>
                </xsl:copy>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>
    
    <!-- 处理schedule节点,在复制完xyz的Item后,添加abc中独有的Item -->
    <xsl:template match="schedule">
        <xsl:copy>
            <!-- 先处理xyz的所有Item(上面的模板会处理替换逻辑) -->
            <xsl:apply-templates select="Item"/>
            <!-- 再添加abc中xyz没有的Item -->
            <xsl:for-each select="document('./abc.xml')/schedule/Item">
                <xsl:variable name="current-measurement" select="measurements/measurement"/>
                <!-- 如果xyz中没有这个measurement的Item,就输出 -->
                <xsl:if test="not(key('abc-item-by-measurement', $current-measurement))">
                    <xsl:copy-of select="."/>
                </xsl:if>
            </xsl:for-each>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

逻辑解释:

  1. <xsl:key>定义:创建一个基于measurement值的索引,快速查找abc.xml中的Item,比原有的document()+XPath匹配更高效。
  2. 修改Item模板:不再只输出匹配的abc Item,而是增加了<xsl:otherwise>分支,保留xyz中没有匹配的Item。
  3. 新增schedule模板:先处理xyz的所有Item(完成替换),然后遍历abc的Item,把那些xyz中不存在的Item补充到结果里。

现在执行原命令:

xsltproc logic.xslt xyz.xml > output.xml

得到的输出会和你的预期完全一致:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<schedule>
 <Item Id="2">
 <measurements>
 <measurement>Alpha</measurement>
 </measurements>
 </Item>
 <Item Id="4">
 <measurements>
 <measurement>Beta</measurement>
 </measurements>
 </Item>
 <Item Id="9">
 <measurements>
 <measurement>Gamma</measurement>
 </measurements>
 </Item>
</schedule>

内容的提问来源于stack exchange,提问作者Sambit Mishra

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 07:22:59