Reputation: 1370
I don't understand why this code fails to fetch a certain node from an xml string. The code below will throw this error: groovy.util.slurpersupport.NodeChildren.attributes() is applicable for argument types: () values: []
Thanks for any explanations how to solve this!
def xml ='''<ProcessDefinition>
<activity name="MergeLogData">
<inputBindings>
<SubmitLogMsgRequest>
<MsgLevel>
<value-of select="$Start/SubmitLogMsgRequest/MsgLevel"/>
</MsgLevel>
<for-each select="SubmitLogMsgRequest/LogMsg">
<LogMsg>
<for-each select="ErrorReport">
<ErrorReport>
<MsgCode>
<value-of select="MsgCode"/>
</MsgCode>
</ErrorReport>
</for-each>
</LogMsg>
</for-each>
</SubmitLogMsgRequest>
</inputBindings>
</activity>
</ProcessDefinition>'''
groovy.util.slurpersupport.GPathResult Process = new XmlSlurper().parseText(xml)
Process.depthFirst().grep { it.name()=="activity" && it.@name=="MergeLogData"}.each{activity->
traverse(activity.inputBindings) // why is it not possible to point to the sub node "inputBindings" here ??
//traverse(activity) this would work, but its pointing to the wrong node, I want it to be "inputBindings"
}
public void traverse(node) {
StringBuffer ret = new StringBuffer()
node.attributes().each(){attribute ->
println "ATTRIBUTE VALUE: $attribute.value"
}
node.children().each {child->
if(child.name().length()>0)
println "NODE name: ${child.name()}"
traverse(child)
}
}
Upvotes: 4
Views: 732
Reputation: 84786
Because inputBindings
is a collection of nodes - there might be multiple inputBindings
. Corrected code below:
def xml ='''<ProcessDefinition>
<activity name="MergeLogData">
<inputBindings>
<SubmitLogMsgRequest>
<MsgLevel>
<value-of select="$Start/SubmitLogMsgRequest/MsgLevel"/>
</MsgLevel>
<for-each select="SubmitLogMsgRequest/LogMsg">
<LogMsg>
<for-each select="ErrorReport">
<ErrorReport>
<MsgCode>
<value-of select="MsgCode"/>
</MsgCode>
</ErrorReport>
</for-each>
</LogMsg>
</for-each>
</SubmitLogMsgRequest>
</inputBindings>
</activity>
</ProcessDefinition>'''
groovy.util.slurpersupport.GPathResult Process = new XmlSlurper().parseText(xml)
Process.depthFirst().grep { it.name()=="activity" && it.@name=="MergeLogData"}.each{activity->
traverse(activity.inputBindings[0])
}
public void traverse(node) {
StringBuffer ret = new StringBuffer()
node.attributes().each(){attribute ->
println "ATTRIBUTE VALUE: $attribute.value"
}
node.children().each {child->
if(child.name().length()>0)
println "NODE name: ${child.name()}"
traverse(child)
}
}
Upvotes: 5