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

XSLT1.0复制XML节点新增元素时XPath报错及多元素丢失问题

问题根因

  1. 单节点新增XPath定位失效:
    • 若输入XML存在默认命名空间,XSLT未声明对应命名空间前缀会导致节点匹配失败
    • 判断条件误用QTY/C186/E6063 != '指定值':该表达式在SG26下无QTY节点时会返回false,无法正确触发新增逻辑,必须使用not(QTY/C186/E6063 = '指定值')才能正确判断“不存在匹配节点”的场景
  2. 多节点新增时单个节点丢失:
    • 多目标值判断共用同一个分支逻辑,未做独立判断
    • 遍历目标值时XPath上下文错误,无法正确关联当前SG26节点下的QTY元素

实现方案

基础逻辑

基于XSLT1.0的身份模板实现全量节点无损复制,单独匹配SG26节点做扩展处理:先复制所有原有子节点,再逐个检查目标E6063值,不存在对应节点则新增。

兼容EXSLT的通用实现(支持任意数量目标值)

大部分XSLT1.0处理器(libxslt、MSXML等)均支持EXSLT扩展,适合目标值较多的场景:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:exsl="http://exslt.org/common" exclude-result-prefixes="exsl">
  <!-- 身份模板:全量复制原有节点和属性 -->
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>

  <!-- SG26节点特殊处理 -->
  <xsl:template match="SG26">
    <xsl:copy>
      <!-- 复制原有所有子节点 -->
      <xsl:apply-templates select="@*|node()"/>
      <!-- 定义需要新增的E6063目标值列表 -->
      <xsl:variable name="targetE6063">
        <val>59</val>
        <val>60</val>
      </xsl:variable>
      <!-- 遍历目标值逐个判断 -->
      <xsl:for-each select="exsl:node-set($targetE6063)/val">
        <xsl:variable name="currentVal" select="."/>
        <!-- 定位到当前SG26节点判断是否存在对应QTY -->
        <xsl:if test="not(../../QTY/C186/E6063 = $currentVal)">
          <QTY>
            <C186>
              <E6063><xsl:value-of select="$currentVal"/></E6063>
              <!-- 可按需补充其他C186子节点,示例为E6060赋值0 -->
              <E6060>0</E6060>
            </C186>
          </QTY>
        </xsl:if>
      </xsl:for-each>
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

无扩展兼容实现(仅支持固定数量目标值)

如果处理器不支持EXSLT,可独立编写每个目标值的判断逻辑,避免节点丢失:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="SG26">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
      <!-- 独立判断E6063=59的场景 -->
      <xsl:if test="not(QTY/C186/E6063 = '59')">
        <QTY>
          <C186>
            <E6063>59</E6063>
            <E6060>0</E6060>
          </C186>
        </QTY>
      </xsl:if>
      <!-- 独立判断E6063=60的场景 -->
      <xsl:if test="not(QTY/C186/E6063 = '60')">
        <QTY>
          <C186>
            <E6063>60</E6063>
            <E6060>0</E6060>
          </C186>
        </QTY>
      </xsl:if>
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 15:18:04