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

使用XSLT匹配属性值复制XML元素并修改内部指定属性值

XSLT提取指定节点并修改属性值实现方案

问题背景

现有如下结构的XML源文件,需要做指定节点提取和属性修改:

<?xml version="1.0" encoding="UTF-8"?>
<FN>
   <START>     
      <VALUE2><VALUE2>
      <VALUE3></VALUE3>
      <VALUE4></VALUE4>
   </START>
   <SET name="-RBS_00">
       <DISH name="-00_01" QR="Buffer">
           <OBJETS>
               <Ingredients total="3">
               </Ingredients>
           </OBJETS>
           <Quantity>
           </Quantity>
       </DISH>
       <DISH name="-00_02" QR="RESTO">
           <OBJETS meat="poulet">
               <Ingredients total="5"></Ingredients>
           </OBJETS>
           <Quantity>
               <Adults numbers="4">
               </Adults>
               <Kids numbers="3">
               </Adults>
           </Quantity>
       </DISH>
       <DISH name="-00_03" QR="DELIVERY">
           <OBJETS meat="jam">
               <Slices total="3"></Slices>
           </OBJETS>
           <OBJETS meat="chicken">
               <Slices total="5"></Slices>
           </OBJETS>
           <OBJETS meat="porc">
               <Slices total="1"></Slices>
           </OBJETS>
           <Quantity>
               <Adults numbers="1">
               </Adults>
               <Kids numbers="1">
               </Adults>
           </Quantity>
       </DISH>
       <DISH name="-00_04" QR="KIDS">
           <OBJETS meat="veggie">
               <Ingredients total="11"></Ingredients>
           </OBJETS>
           <Quantity>
               <Adults numbers="10">
               </Adults>
               <Kids numbers="2">
               </Adults>
           </Quantity>
       </DISH>
     </SET>
</FN>

需求说明

  • 仅提取name属性值为-00_03的完整<DISH>元素,丢弃其他所有无关节点
  • 将提取到的DISH元素内部,所有meat属性值为porc的项修改为meat="cheese"
    最终输出XML结构如下:
<DISH name="-00_03" QR="DELIVERY">
    <OBJETS meat="jam">
        <Slices total="3"></Slices>
    </OBJETS>
    <OBJETS meat="chicken">
        <Slices total="5"></Slices>
    </OBJETS>
    <OBJETS meat="cheese">
         <Slices total="1"></Slices>
    </OBJETS>
    <Quantity>
        <Adults numbers="1"></Adults>
        <Kids numbers="1"></Adults>
    </Quantity>
</DISH>

原有代码问题

之前编写的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" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:template match="/FN/SET">
    <xsl:copy>
        <xsl:copy-of select="*"/>
        <xsl:copy-of select="//DISH [@name='-00_03']"/>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>
  • 模板匹配<SET>节点做全量复制,会带出所有外层节点和其他无关DISH内容,不符合仅输出目标DISH的要求
  • 使用xsl:copy-of做深拷贝是一次性复制所有内容,无法在复制过程中修改内部节点的属性值

实现代码(XSLT 1.0 全版本兼容)

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<!-- 身份模板:默认原样复制所有匹配到的节点、属性、文本内容 -->
<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>

<!-- 根节点规则:跳过所有外层无关节点,只定位到目标DISH节点处理 -->
<xsl:template match="/">
    <xsl:apply-templates select="//DISH[@name='-00_03']"/>
</xsl:template>

<!-- 属性修改规则:匹配所有值为porc的meat属性,替换值为cheese -->
<xsl:template match="@meat[.='porc']">
    <xsl:attribute name="meat">cheese</xsl:attribute>
</xsl:template>

</xsl:stylesheet>

逻辑说明

  • 身份模板是XSLT处理这类「大部分内容原样复制、少部分内容修改」需求的通用基础,会递归处理所有节点,不需要逐节点写复制逻辑
  • 根节点处理规则直接过滤掉所有非目标内容,只把目标DISH节点送入后续处理流程
  • 属性修改规则优先级高于身份模板,匹配到需要修改的meat属性时自动替换值,其余属性和节点全部按原样复制

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 23:27:35