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

如何用简洁XSLT修改XML元素并保留其余标签结构?

问题:修改指定XML元素同时保留原有结构的XSLT实现

需求是将所有<price>元素内容改为“i win”,但现有XSLT转换后非<price>的标签全部被移除,问是否无需为每个标签编写模板就能修改指定元素并保留原有XML结构?


原始XML文档

<bookstore>
  <book genre="autobiography" publicationdate="1981" ISBN="1-861003-11-0">
    <title>The Autobiography of Benjamin Franklin</title>
    <author>
      <first-name>Benjamin</first-name>
      <last-name>Franklin</last-name>
    </author>
    <price>8.99</price>
  </book>
  <book genre="novel" publicationdate="1967" ISBN="0-201-63361-2">
    <title>The Confidence Man</title>
    <author>
      <first-name>Herman</first-name>
      <last-name>Melville</last-name>
    </author>
    <price>11.99</price>
  </book>
  <book genre="philosophy" publicationdate="1991" ISBN="1-861001-57-6">
    <title>The Gorgias</title>
    <author>
      <name>Plato</name>
    </author>
    <price>9.99</price>
  </book>
</bookstore>

现有XSLT文件

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method="xml" indent="yes"/>

    <xsl:template match = "/bookstore/book/price">
        <price>i win</price>
    </xsl:template>
</xsl:stylesheet>

VB.NET执行代码

Module Module1

    Sub Main()
        Dim xslt = New XslCompiledTransform
        dim curDir = My.Computer.FileSystem.CurrentDirectory
        xslt.Load(curDir & "\testtransform.xsl")
        xslt.Transform(curDir & "\testinv2.xml",curDir & "\outinv.xml")
    End Sub

End Module

转换后输出结果

<?xml version="1.0" encoding="utf-8"?>
  
    The Autobiography of Benjamin Franklin
    
      Benjamin
      Franklin
    
    <price>i win</price>
  
  
    The Confidence Man
    
      Herman
      Melville
    
    <price>i win</price>
  
  
    The Gorgias
    
      Plato
    
    <price>i win</price>

解答

完全可以不用为每个标签单独编写模板,问题根源在于XSLT的默认模板行为:

  • 元素和根节点的默认模板会递归处理子节点,但不会复制元素本身,仅输出文本内容
  • 文本节点的默认模板会直接输出文本

现有XSLT只定义了<price>的匹配模板,其余元素均走默认模板,导致标签被丢弃,仅保留文本。

要保留原有结构,只需添加身份模板——它会复制所有未被自定义模板匹配的节点(包括元素、属性、文本等),同时让自定义模板处理<price>元素:

修改后的XSLT

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method="xml" indent="yes"/>

    <!-- 身份模板:复制所有未被自定义模板匹配的节点 -->
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

    <!-- 自定义模板:修改price元素内容 -->
    <xsl:template match="price">
        <price>i win</price>
    </xsl:template>
</xsl:stylesheet>

说明

  • match="@*|node()"匹配所有属性(@*)和各类节点(元素、文本、注释等)
  • <xsl:copy>复制当前节点本身,<xsl:apply-templates>递归处理子节点,完整保留原有XML结构
  • 自定义<price>模板优先级高于身份模板,会覆盖处理所有<price>元素,将内容替换为“i win”

使用该XSLT转换后,所有非<price>标签都会被保留,仅<price>元素内容被修改。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 09:15:22