从xml中获取节点

时间:2014-12-27 08:15:30

标签: xml groovy xml-parsing xmlslurper

我不明白为什么这段代码无法从xml字符串中获取某个节点。 下面的代码将抛出此错误: groovy.util.slurpersupport.NodeChildren.attributes()适用于参数类型:()值:[]

感谢您解释如何解决这个问题!

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)
    }          
}     

1 个答案:

答案 0 :(得分:4)

由于inputBindings是节点的集合,因此可能有多个inputBindings。更正了以下代码:

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)
    }          
}