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

Jenkins Groovy按属性选XML节点并添加子节点报错求助

解决XmlSlurper操作XML时的节点查找与子节点添加问题

问题场景

现有如下XML文件:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<testsuites>
  <testsuite name="xray" tests="2" failure="0" timestamp="2023-07-07T05:25:33.339Z" skipped="0" failure-evaluating="0">
    <testcase name="SPT-4323" classname="testim.io.test" time="52.597" ownedBy="Staysure Automation" ownerEmail="automationteam@staysure.co.uk">
    </testcase>
    <testcase name="SPT-4331" classname="testim.io.test" time="20.823" ownedBy="Automation Team" ownerEmail="nipunam@intervest.lk">
    </testcase>
  </testsuite>
</testsuites>

需求是选中<testcase name="SPT-4323">节点并添加子节点,但尝试以下两种写法均报错groovy.util.slurpersupport.NodeChildren.find:

xml.testsuite.find{it.@name == 'SPT-4323'}.appendNode( fragmentToAdd )
xml.testsuite.testcase.find{it.@name == 'SPT-4323'}.appendNode( fragmentToAdd )

完整的Jenkins Pipeline阶段代码如下:

stage('Update_XML') {
        try{
            def File = readFile "${env.WORKSPACE}/testim-tests-report.xml"
            echo "${File}"
            def xml = new XmlSlurper().parseText(File)
            def xrayIDs = xml.testsuite.testcase.collect { it.@name }
            
            echo "Xray IDs are ${xrayIDs}"
                            
            def toadd = '''<properties>
                            <property name="test_key" value="SPT-4323" />
                        </properties>'''
            
            fragmentToAdd = new XmlSlurper( false, true ).parseText( toadd )

            xml.testsuite.find{it.@name == 'SPT-4323'}.appendNode( fragmentToAdd )
            
            String outxml = groovy.xml.XmlUtil.serialize( xml )
            echo "Output XML ${outxml}"
            
        } catch(Exception) {
            build_status = false
            echo Exception.toString()
        }
    };

问题原因

  1. 第一种写法逻辑错误:testsuite的name属性是xray,并非目标的SPT-4323,路径和属性匹配完全错误;
  2. 第二种写法存在类型兼容问题:XmlSlurper解析的节点集合调用find后,直接追加另一个XmlSlurper解析的节点会出现类型不匹配,导致报错;
  3. xml.testsuite返回的是NodeChildren类型,直接调用find不符合XmlSlurper的节点操作逻辑。

解决方案

修改后的Pipeline代码如下:

stage('Update_XML') {
    try{
        def fileContent = readFile "${env.WORKSPACE}/testim-tests-report.xml"
        echo "${fileContent}"
        def xml = new XmlSlurper().parseText(fileContent)
        
        // 准确定位目标testcase节点
        def targetTestCase = xml.testsuite.testcase.find { it.@name == 'SPT-4323' }
        
        // 用MarkupBuilder构建可兼容的子节点
        def writer = new StringWriter()
        def builder = new groovy.xml.MarkupBuilder(writer)
        builder.properties {
            property(name: "test_key", value: "SPT-4323")
        }
        def fragmentToAdd = new XmlSlurper().parseText(writer.toString())
        
        // 给目标节点追加子节点
        targetTestCase.appendNode(fragmentToAdd)
        
        // 序列化输出修改后的XML
        String outxml = groovy.xml.XmlUtil.serialize(xml)
        echo "Output XML ${outxml}"
        
        // 可选:将修改后的XML写回文件
        writeFile file: "${env.WORKSPACE}/updated-testim-tests-report.xml", text: outxml
        
    } catch(Exception e) {
        build_status = false
        echo e.toString()
    }
};

关键修改点

  • 节点定位修正:通过xml.testsuite.testcase.find { it.@name == 'SPT-4323' }直接匹配目标节点,确保路径和属性完全对应;
  • 子节点构建优化:改用MarkupBuilder生成节点内容,再用XmlSlurper解析,避免不同解析实例导致的节点类型不兼容问题;
  • 异常处理完善:捕获异常时指定变量e,能输出更详细的错误信息;
  • 增加写回步骤:可选操作,将修改后的XML保存到文件,满足实际场景的持久化需求。

验证效果

执行修改后的代码后,目标testcase节点会成功添加<properties>子节点,最终XML如下:

<?xml version="1.0" encoding="UTF-8"?>
<testsuites>
  <testsuite name="xray" tests="2" failure="0" timestamp="2023-07-07T05:25:33.339Z" skipped="0" failure-evaluating="0">
    <testcase name="SPT-4323" classname="testim.io.test" time="52.597" ownedBy="Staysure Automation" ownerEmail="automationteam@staysure.co.uk">
      <properties>
        <property name="test_key" value="SPT-4323"/>
      </properties>
    </testcase>
    <testcase name="SPT-4331" classname="testim.io.test" time="20.823" ownedBy="Automation Team" ownerEmail="nipunam@intervest.lk"/>
  </testsuite>
</testsuites>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 19:32:51