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

Groovy XmlParser删除XML中.py关联testcase节点并写回文件

Groovy实现XML过滤.py后缀testcase节点方案

需求说明

实现XML文件处理逻辑:加载XML文件,删除所有file属性包含.py后缀的testcase条目后将内容写回文件,脚本需适配Jenkins运行环境,支持后续通过readFile函数读取处理后的文件。

原有代码错误点

  • 遍历层级错误:直接在根节点testSuites上执行查找,实际testcase是根节点的直接子节点,查找范围错误
  • 删除逻辑无效:调用了未定义的articles.remove()方法,没有将匹配节点从父节点下移除
  • 属性读取方式冗余:通过@file取属性值后不需要额外调用.text()方法
  • 统计值未更新:处理完成后没有同步更新根节点tests属性的用例计数,和预期输出不符
  • 环境适配缺失:直接使用本地文件IO,没有兼容Jenkins流水线的readFile/writeFile步骤

可直接运行的正确代码

import groovy.xml.XmlParser
import groovy.xml.XmlNodePrinter
import java.io.PrintWriter
import java.io.FileWriter

// === Jenkins环境请替换为以下读文件逻辑,注释本地读代码 ===
// String fileContents = readFile "./report.xml"
// === 本地运行读文件逻辑 ===
String fileContents = new File('report.xml').getText('UTF-8')

// 初始化解析器,关闭DTD、命名空间校验避免解析异常
def xmlParser = new XmlParser(false, false)
def testSuiteRoot = xmlParser.parseText(fileContents)

// 查找所有file属性为.py后缀的testcase节点,从父节点移除
testSuiteRoot.testcase.findAll { node ->
    node.attribute('file')?.endsWith('.py')
}.each { targetNode ->
    targetNode.parent().remove(targetNode)
}

// 更新根节点tests统计值为剩余用例数
testSuiteRoot.@tests = testSuiteRoot.testcase.size().toString()

def outputPath = "report.xunit"
// === Jenkins环境请替换为以下写文件逻辑,注释本地写代码 ===
// writeFile file: outputPath, text: groovy.xml.XmlUtil.serialize(testSuiteRoot)
// === 本地运行写文件逻辑 ===
def nodePrinter = new XmlNodePrinter(new PrintWriter(new FileWriter(outputPath, false)))
nodePrinter.preserveWhitespace = true
nodePrinter.print(testSuiteRoot)

效果说明

针对提供的示例XML,运行后输出结果完全符合预期:

  • 仅保留file属性为.xml后缀的2条testcase记录
  • 所有带.py后缀的testcase被全部删除
  • 根节点tests属性自动更新为"2"

使用注意事项

  • Jenkins流水线中运行时,直接替换文件读写部分为readFile/writeFile步骤即可,不需要做其他修改
  • 后缀判断使用endsWith('.py')而非contains('.py'),可以避免文件名中间包含.py字符串导致的误删问题
  • 解析器关闭校验可以兼容部分格式不完全规范的xunit报告文件,减少解析报错

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 02:51:22