Как вернуться обратно в дерево XML, чтобы добраться до смежного дочернего элемента, используя родительский метод

Учитывая следующий 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

Более странно node.parent().size() возвращает 1, когда я ожидаю, что он вернет 3 в соответствии с приведенным выше XML

Мои вопросы:

  1. Мой код правильный и почему не работает?

  2. Это самый короткий способ достижения ожидаемого результата?

  3. Зачем node.parent().size() возвращается 1? То же самое касается node.parent().parent().size(), node.parent().parent().parent().size() и так далее...

3 ответа

Ты можешь попробовать

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

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

Что-то быстрое и грязное, но это должно работать:

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

Ты можешь использовать:

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
}
Другие вопросы по тегам