2010-09-19 3 views
1

J'ai analysé du code HTML à l'aide de XmlSlurper. Maintenant, je veux itérer tous les enfants avec un nom d'élément donné.Itérer tous les enfants avec un prénom en utilisant GPathResult retourné par XmlSlurper

Ce que j'ai maintenant est le code suivant snippet

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

Il fonctionne, mais tout simplement pas assez groovy. Je voudrais simplement écrire quelque chose comme ça

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

Si je le fais de cette façon, GPath se plaint qu'il n'y a pas de propriété avec le nom « a ». Une idée s'il y a une syntaxe facile pour formuler cette itération?

Répondre

3

Malheureusement, il n'y a actuellement aucun moyen dans Groovy pour effectuer ce que vous demandez.
Lorsque vous effectuez cette opération sur un GPathResult (ou l'un de ses enfants)

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

Ce qui est fait est que pour chaque « » un appel à la méthode GPathResult.getProperty() est effectué. Et cette méthode comme seulement quelques sucre syntaxique valide (*, **, .. et @). Cela signifie que si vous n'utilisez pas l'un d'entre eux, il suppose que la propriété existe réellement pour chaque noeud que vous ciblez.

Si vous souhaitez disposer d'un opérateur null-safe conditionnel pour parcourir votre arborescence, vous devez demander l'ajout d'un préfixe de syntaxe syntaxique (par exemple "? A") dans la classe GPathResult. Peut-être que vous pouvez le faire en utilisant la méta-classe expando et en surchargeant la méthode getProperty, mais je ne l'ai pas essayé.

1

utilisation fermeture récursive:

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