I have a project that has the following XML file (config.xml for a Cordova project) ...
<?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>
....
All I want to do is read the value of the version
attribute (to give me the string 1.3.0.b4
) of the root element (widget
). Following the example here where it says to use the .@
to get an attribute.
I have the following in my Jenkins file script:
script {
def xml = readFile "${env.WORKSPACE}/config.xml"
def rootNode = new XmlParser().parseText(xml)
def version = rootNode.@version
echo 'version is...'
echo version
But when I run it, I get the following error:
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.onGetAttribute(SandboxInterceptor.java:436)
at org.kohsuke.groovy.sandbox.impl.Checker$8.call(Checker.java:370)
at org.kohsuke.groovy.sandbox.impl.Checker.checkedGetAttribute(Checker.java:375)
at com.cloudbees.groovy.cps.sandbox.SandboxInvoker.getAttribute(SandboxInvoker.java:37)
I have tried rootNode.@version
(as above) rootNode[0].@version
and rootNode[3].@version
but nothing works.
What's wrong with the above?
If I use the following:
def xml = readFile "${env.WORKSPACE}/config.xml"
def rootNode = new XmlParser().parseText(xml)
def version = rootNode.text()
echo 'version is...'
echo version
it prints out My app description
which is a bit weird (it jumps down to the description node)
I tried using the following:
def rootNode = new XmlSlurper().parse("${env.WORKSPACE}/config.xml")
def version = rootNode.@'version'
but I still get a similar error:
org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException: No such field found: field groovy.util.slurpersupport.NodeChild version
at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor.unclassifiedField(SandboxInterceptor.java:425)
at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor.onGetAttribute(SandboxInterceptor.java:436)
at org.kohsuke.groovy.sandbox.impl.Checker$8.call(Checker.java:370)
at org.kohsuke.groovy.sandbox.impl.Checker.checkedGetAttribute(Checker.java:375)
at com.cloudbees.groovy.cps.sandbox.SandboxInvoker.getAttribute(SandboxInvoker.java:37)
at com.cloudbees.groovy.cps.impl.AttributeAccessBlock.rawGet(AttributeAccessBlock.java:20)
at WorkflowScript.run(WorkflowScript:15)
at ___cps.transform___(Native Method)
If I call echo rootNode.text()
, once again it seems to just print out the contents of the first 3 tags inside the main ,widget
tag, i.e. My AppMy app descriptionmycom.com.au
.
I tested some more in context of being able to also modify the attribute, and found out when using the []
access, the @
selector for attributes actually works. It seems this leads to use different methods under the hood which you can approve in jenkins (getAt
and putAt
) .
We can simply use
def rootNode = new XmlParser().parseText(xml)
println rootNode['@version']
There seems some bug regarding the direct access to the attributes with the @
selector on the groovy.util.Node object with the script sandbox.
A workaround is to use the .attributes()
method to get the full Map of attributes, and access the value via the key like the following:
def rootNode = new XmlParser().parseText(xml)
println rootNode.attributes()['version']
This will fail the first run and promt you to approve the use of method groovy.util.Node attributes
, but once approved will work.