除XmlSlurper与XmlParser外,Jenkins Pipeline还有哪些XML解析方法?
无XmlSlurper/XmlParser时Jenkins Pipeline解析XML的替代方法
你有如下结构的Servers.xml文件:
<Servers> <Environment id="1" name="Jenkins"> <Server id="1" ip="192.168.0.1" /> <Server id="2" ip="10.21.22.30" /> </Environment> <Environment id="2" name="Pipe"> <Server id="1" ip="192.10.2.77" /> <Server id="2" ip="122.30.45.99" /> </Environment> </Servers>
需要根据Environment标签的name属性修改对应Server节点的ip值,但XmlSlurper和XmlParser在Jenkins Pipeline中被禁止,且无法申请签名批准或安装插件,以下是两种可行的替代方案:
方案1:正则表达式(适合结构固定的XML)
因为你的XML结构规则明确,用正则匹配替换是最直接的方式,无需依赖任何XML解析工具:
// 配置参数 def xmlFilePath = "Servers.xml" def targetEnvName = "Jenkins" def targetServerId = "1" def newIpAddress = "192.168.0.100" // 读取原XML内容 def originalContent = readFile xmlFilePath // 构造正则,匹配指定Environment下目标Server的ip属性 def replaceRegex = /(<Environment[^>]+name="${targetEnvName}"[^>]*>\s*<Server[^>]+id="${targetServerId}"[^>]+ip=")[^"]+(")/ // 执行替换 def updatedContent = originalContent.replaceAll(replaceRegex, "\$1${newIpAddress}\$2") // 将修改后的内容写回文件 writeFile file: xmlFilePath, text: updatedContent
注意:这种方法仅适用于XML结构稳定的场景,如果后续XML标签排版、属性顺序发生变化,正则可能失效,但对你当前的需求完全适用。
方案2:Java原生XML API(功能更稳定)
Groovy可以直接调用Java自带的XML处理API,通过@NonCPS注解避开Pipeline的序列化限制(方法内仅处理字符串和Java对象,不调用Pipeline步骤):
@NonCPS def updateServerIp(String xmlContent, String envName, String serverId, String newIp) { // 初始化XML解析器 def docFactory = javax.xml.parsers.DocumentBuilderFactory.newInstance() def docBuilder = docFactory.newDocumentBuilder() def xmlDoc = docBuilder.parse(new ByteArrayInputStream(xmlContent.getBytes("UTF-8"))) // 遍历所有Environment节点 def envNodes = xmlDoc.getElementsByTagName("Environment") for (int i = 0; i < envNodes.getLength(); i++) { def currentEnv = envNodes.item(i) if (currentEnv.getAttribute("name") == envName) { // 遍历当前Environment下的Server节点 def serverNodes = currentEnv.getElementsByTagName("Server") for (int j = 0; j < serverNodes.getLength(); j++) { def currentServer = serverNodes.item(j) if (currentServer.getAttribute("id") == serverId) { currentServer.setAttribute("ip", newIp) break } } break } } // 将修改后的XML文档转换为字符串 def transformer = javax.xml.transform.TransformerFactory.newInstance().newTransformer() transformer.setOutputProperty(javax.xml.transform.OutputKeys.INDENT, "yes") transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4") def stringWriter = new StringWriter() transformer.transform(new javax.xml.transform.dom.DOMSource(xmlDoc), new javax.xml.transform.stream.StreamResult(stringWriter)) return stringWriter.toString() } // 调用示例 def xmlFilePath = "Servers.xml" def originalContent = readFile xmlFilePath def updatedContent = updateServerIp(originalContent, "Pipe", "2", "122.30.45.100") writeFile file: xmlFilePath, text: updatedContent
这种方法能处理更复杂的XML结构,稳定性更强,即使XML排版变化也不影响解析。
内容的提问来源于stack exchange,提问作者Meng Xiangrui
相关产品推荐
相关产品推荐

