如何通过Groovy查找XML文件所有匹配值并替换为新值
Groovy实现XML指定内容替换方案
方案选择说明
针对XML内容替换场景,提供两种可直接运行的实现,可根据实际需求选择:
- 结构化解析替换:推荐方案,不会破坏XML结构,不会误改标签、属性中的同名内容,仅处理节点文本
- 纯文本替换:适合需要100%保留原文件排版格式、XML结构简单的场景
方案1:结构化XML解析替换(推荐)
该方案通过遍历XML节点实现精确替换,只会修改文本内容完全匹配目标值的节点,不会误改类似01900397531030901-01这类包含目标串的长文本,也不会破坏XML命名空间、标签结构。
import groovy.xml.XmlSlurper import groovy.xml.XmlUtil import java.nio.file.Files import java.nio.file.Paths // 路径与替换规则配置 def sourceXmlPath = "./file.xml" def outputXmlPath = "./file_updated.xml" def targetContent = "01900397531030901" def replaceContent = "custom text" // 加载并解析XML,关闭校验避免命名空间声明缺失报错 def xmlRoot = new XmlSlurper(false, false).parse(Files.newInputStream(Paths.get(sourceXmlPath))) // 深度遍历所有XML节点 xmlRoot.'**'.each { node -> // 仅替换文本完全匹配的节点 if (node.text() == targetContent) { node.replaceBody(replaceContent) } } // 输出替换后的新XML文件 Files.writeString(Paths.get(outputXmlPath), XmlUtil.serialize(xmlRoot))
针对给出的示例XML,该脚本只会替换<m:RefnumValue>01900397531030901</m:RefnumValue>节点的内容,其余节点保持不变。
方案2:纯文本正则替换
如果需要完全保留原XML的缩进、换行格式,不需要校验XML合法性,可以使用纯文本替换方案。该方案通过单词边界匹配避免误替换长文本中的子串,但若标签名、属性值中存在完全匹配的目标串也会被同步替换。
import java.nio.file.Files import java.nio.file.Paths import java.util.regex.Pattern // 路径与替换规则配置 def sourceXmlPath = "./file.xml" def outputXmlPath = "./file_updated.xml" def targetContent = "01900397531030901" def replaceContent = "custom text" // 读取原文件内容 def rawContent = Files.readString(Paths.get(sourceXmlPath)) // 增加前后字符边界,避免替换长文本中的匹配子串 def replacedContent = rawContent.replaceAll( /(?<!\w)${Pattern.quote(targetContent)}(?!\w)/, replaceContent ) // 输出新文件 Files.writeString(Paths.get(outputXmlPath), replacedContent)
调整说明
如果需求是替换所有出现目标字符串的位置(不需要完全匹配整个节点内容,比如要把01900397531030901-01中的前缀也替换掉),可以做如下修改:
- 方案1:将节点判断逻辑改为
if (node.text().contains(targetContent)),替换逻辑改为node.replaceBody(node.text().replace(targetContent, replaceContent)) - 方案2:直接使用
rawContent.replace(targetContent, replaceContent)去掉正则边界限制即可
内容的提问来源于stack exchange,提问作者Beksultan Nurkulov
相关产品推荐
相关产品推荐

