Jenkins - 如何设置 XML 属性然后写回 XML 文件
Jenkins - how to set an XML attribute and then write back to an XML file
在我的 之后,向我展示了如何读取 XML 属性,现在我的最后一个任务是 设置 属性,例如我将递增读取属性然后回写。
所以,我又得到了以下 XML 文件:
<?xml version='1.0' encoding='utf-8'?>
<widget android-versionCode="16" id="com.mycomp.myapp" ios-CFBundleVersion="15" version="1.3.0.b4" windows-packageVersion="1.2.6.0" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0">
<name>My App</name>
<description>My app description</description>
<author>mycom.com.au</author>
而且我了解到,根据帮助,以下内容不起作用:
def xml = readFile "${env.WORKSPACE}/config.xml"
def rootNode = new XmlParser().parseText(xml)
def version = rootNode.@version
但以下会:
def version = rootNode.attributes()['version']
我现在似乎在写回属性时遇到同样的问题。
根据 this post 我尝试了以下设置属性:
def filePath = "${env.WORKSPACE}/config.xml"
def xml = readFile filePath
def rootNode = new XmlParser().parseText(xml)
rootNode.@version = "12345"
def writer = new FileWriter(filePath)
new XmlNodePrinter(new PrintWriter(writer)).print(rootNode)
但是我在尝试读取属性时遇到了类似的错误:
org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException: No such field found: field groovy.util.Node version
at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor.unclassifiedField(SandboxInterceptor.java:425)
at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor.onSetAttribute(SandboxInterceptor.java:447)
at org.kohsuke.groovy.sandbox.impl.Checker.call(Checker.java:405)
at org.kohsuke.groovy.sandbox.impl.Checker.checkedSetAttribute(Checker.java:411)
我在 Groovy 操场上尝试过,它似乎有效,但在詹金斯这里不行。
因此,看起来 .@version
语法再次不起作用,我无法找到替代调用(就像获取属性一样)来设置属性。
我该怎么做?
经过更多测试后我发现,我们可以简单地使用 []
访问中的 @
选择器(编辑:它称为 map notation),似乎脚本沙箱可以处理这个。它在 getAt()
和 putAt()
中转换为 jenkins 允许批准的引擎盖。
node() {
def xml = readFile "${env.WORKSPACE}/config.xml"
def rootNode = new XmlParser().parseText(xml)
print rootNode['@version']
rootNode['@version'] = 123
print rootNode['@version']
}
结果
Running on Jenkins in /var/jenkins_home/workspace/xmltest
[Pipeline] {
[Pipeline] readFile
[Pipeline] echo
1.3.0.b4
[Pipeline] echo
123
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
Finished: SUCCESS
在我的
所以,我又得到了以下 XML 文件:
<?xml version='1.0' encoding='utf-8'?>
<widget android-versionCode="16" id="com.mycomp.myapp" ios-CFBundleVersion="15" version="1.3.0.b4" windows-packageVersion="1.2.6.0" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0">
<name>My App</name>
<description>My app description</description>
<author>mycom.com.au</author>
而且我了解到,根据帮助,以下内容不起作用:
def xml = readFile "${env.WORKSPACE}/config.xml"
def rootNode = new XmlParser().parseText(xml)
def version = rootNode.@version
但以下会:
def version = rootNode.attributes()['version']
我现在似乎在写回属性时遇到同样的问题。
根据 this post 我尝试了以下设置属性:
def filePath = "${env.WORKSPACE}/config.xml"
def xml = readFile filePath
def rootNode = new XmlParser().parseText(xml)
rootNode.@version = "12345"
def writer = new FileWriter(filePath)
new XmlNodePrinter(new PrintWriter(writer)).print(rootNode)
但是我在尝试读取属性时遇到了类似的错误:
org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException: No such field found: field groovy.util.Node version
at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor.unclassifiedField(SandboxInterceptor.java:425)
at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor.onSetAttribute(SandboxInterceptor.java:447)
at org.kohsuke.groovy.sandbox.impl.Checker.call(Checker.java:405)
at org.kohsuke.groovy.sandbox.impl.Checker.checkedSetAttribute(Checker.java:411)
我在 Groovy 操场上尝试过,它似乎有效,但在詹金斯这里不行。
因此,看起来 .@version
语法再次不起作用,我无法找到替代调用(就像获取属性一样)来设置属性。
我该怎么做?
经过更多测试后我发现,我们可以简单地使用 []
访问中的 @
选择器(编辑:它称为 map notation),似乎脚本沙箱可以处理这个。它在 getAt()
和 putAt()
中转换为 jenkins 允许批准的引擎盖。
node() {
def xml = readFile "${env.WORKSPACE}/config.xml"
def rootNode = new XmlParser().parseText(xml)
print rootNode['@version']
rootNode['@version'] = 123
print rootNode['@version']
}
结果
Running on Jenkins in /var/jenkins_home/workspace/xmltest
[Pipeline] {
[Pipeline] readFile
[Pipeline] echo
1.3.0.b4
[Pipeline] echo
123
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
Finished: SUCCESS