user955732
user955732

Reputation: 1370

Fetching node from xml

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

Answers (1)

Opal
Opal

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

Related Questions