如何使用父方法导航回XML树以获取相邻的子元素

时间:2014-07-23 19:00:18

标签: xml parsing groovy xmlslurper

给出以下XML:

<list version="1.0">
    <meta>...</meta>
    <resources start="0" count="167">
        <resource classname="Quote">
            <field name="name">USD/KRW</field>
            <field name="price">1024.400024</field>
            <field name="symbol">KRW=X</field>
        </resource>
        ...
     </resources>
</list>

为了找到合适的<resource>并获得price,我会执行以下操作:

def slurper = new XmlSlurper()
def result = slurper.parse(XML_URL)
def node = result.depthFirst().find { it.text() == "KRW=X" }
println node.parent().find { it['@name'] == "price" }.text()

但结果是parent()未实现与文档不完全匹配的find(Closure)http://groovy.codehaus.org/gapi/groovy/util/slurpersupport/GPathResult.html

当我希望它按照上面的XML

返回3时,更奇怪的node.parent().size()会返回1

我的问题:

  1. 我的代码是否正确,为什么不起作用?

  2. 这是达到预期结果的最短途径吗?

  3. 为什么node.parent().size()返回1?同样适用于node.parent().parent().size()node.parent().parent().parent().size()等等......

3 个答案:

答案 0 :(得分:1)

你能试试吗

def resource = result.'**'.find { 
    it.field.@name == 'symbol' &&
    it.field.text() == 'KRW=X'
}

println resource?.'**'.find {
    it.@name == 'price'
}?.text()

答案 1 :(得分:0)

快速而又脏的东西,但这应该有效:

new XmlSlurper().parseText("""
<list version="1.0">
    <meta>...</meta>
    <resources start="0" count="167">
        <resource classname="Quote">
            <field name="name">USD/KRW</field>
            <field name="price">1024.400024</field>
            <field name="symbol">KRW=X</field>
        </resource>

        <resource classname="Quote">
            <field name="name">USD/KRW</field>
            <field name="price">2222</field>
            <field name="symbol">KRW=Y</field>
        </resource>

     </resources>
</list>
""").resources.resource.find{ 
    it.field.find {it.@name == "symbol" && it.text() == "KRW=X"}
}.field.find {it.@name == "price"}.text()

答案 2 :(得分:0)

您可以使用:

def desiredPrice = new XmlSlurper().parse( XML_URL ).'**'.findResult { 
    it.name() == 'field' && it.@name == 'symbol' && it.text() == 'KRW=X' ? 
        it.parent().field.find { it.@name == 'price' }.text() : null
}