Выполните итерацию всех детей с заданным именем, используя GPathResult, возвращаемый XmlSlurper - PullRequest
1 голос
/ 19 сентября 2010

Я проанализировал некоторые HTML, используя XmlSlurper. Теперь я хочу перебрать всех детей с заданным именем элемента.

Теперь у меня есть следующий фрагмент кода

html.'**'.findAll { it.name() == 'a' }.each {
  println it
}

Это работает, но просто недостаточно хорошо. Я хотел бы просто написать что-то вроде этого

html.'**'.a.each {
  println it
}

Если я делаю это таким образом, GPath жалуется, что нет свойства с именем 'a'. Любая идея, если есть простой синтаксис для формулировки этой итерации?

Ответы [ 2 ]

3 голосов
/ 22 сентября 2010

К сожалению, в Groovy в настоящее время нет способа выполнить то, что вы просите.
Когда вы выполняете такую ​​операцию над GPathResult (или любым из его дочерних элементов)

html."**".a.b.c

Что сделано для каждого "." вызов метода GPathResult.getProperty () . И этот метод, как только несколько допустимых синтаксических сахара (*, **, .. и @). Это означает, что если вы не используете один из них, предполагается, что свойство действительно существует для каждого целевого узла.

Если вы хотите иметь условный нулевой безопасный оператор для обхода вашего дерева, он запросит либо добавление синтаксического префикса сахара (например, «? A») в классе GPathResult. Может быть, вы можете достичь этого, используя метакласс расширения и переопределив метод getProperty, но я не пробовал.

1 голос
/ 10 марта 2013

Использовать рекурсивное закрытие:

def out = new StringBuffer()

def printNode
printNode = { o,node ->         
    o << '<' + node.name()
    node.attributes().each{ o << ' ' + it.key + '="' + it.value + '"' }
    o << '>'
    node.children().each{ printNode(out,it) }
    o << '</' + node.name() + '>'  
}

html.'**'.findAll { it.name() == 'a' }.each { printNode(out,it) }

println out.toString()
...