À l'aide de XmlSlurper: Comment sélectionner les sous-éléments lors de l'itération sur une GPathResult
Je suis en train d'écrire un analyseur HTML, qui utilise TagSoup de passer une structure formée de XMLSlurper.
Voici généralisées code:
def htmlText = """
<html>
<body>
<div id="divId" class="divclass">
<h2>Heading 2</h2>
<ol>
<li><h3><a class="box" href="#href1">href1 link text</a> <span>extra stuff</span></h3><address>Here is the address<span>Telephone number: <strong>telephone</strong></span></address></li>
<li><h3><a class="box" href="#href2">href2 link text</a> <span>extra stuff</span></h3><address>Here is another address<span>Another telephone: <strong>0845 1111111</strong></span></address></li>
</ol>
</div>
</body>
</html>
"""
def html = new XmlSlurper(new org.ccil.cowan.tagsoup.Parser()).parseText( htmlText );
html.'**'.grep { it.@class == 'divclass' }.ol.li.each { linkItem ->
def link = linkItem.h3.a.@href
def address = linkItem.address.text()
println "$link: $address\n"
}
J'attendrais la chaque pour me laisser sélectionner chaque 'li' à son tour afin que je puisse récupérer le correspondant href et les détails de l'adresse. Au lieu de cela, j'obtiens ce résultat:
#href1#href2: Here is the addressTelephone number: telephoneHere is another addressAnother telephone: 0845 1111111
J'ai vérifié divers sur le web et ces soit régler XML, ou sont one-liner exemples comme "récupérer tous les liens à partir de ce fichier". Il semble que l'it.h3.a.@href l'expression est de collecter tous les hrefs dans le texte, même si je suis de passage une référence pour les parents de li' nœud.
Pouvez-vous laissez-moi savoir:
- Pourquoi je me fais de la sortie montré
- Comment je peux récupérer le href d'adresse/de paires pour chaque 'li' élément
Grâce.
OriginalL'auteur Andrew Whitehouse | 2009-11-04
Vous devez vous connecter pour publier un commentaire.
Remplacer grep avec trouver:
ensuite, vous aurez
grep renvoie une liste de tableaux, mais de trouver renvoie une NodeChild classe:
résultats dans:
ainsi, si vous vouliez utiliser grep, vous pouvez nid de l'autre chacun comme cela pour qu'il fonctionne
Longue histoire courte, dans votre cas, utilisez la trouver plutôt que de grep.
OriginalL'auteur mbrevoort
C'est une question délicate. Quand il y a juste un élément class='divclass" la réponse précédente est sûr, c'est bien. Si il y avait plusieurs résultats de grep, puis un find() pour un résultat unique n'est pas la réponse. Soulignant que le résultat est une liste de tableaux est correct. L'insertion d'un extérieur imbriqués .chacun() boucle fournit un GPathResult la fermeture paramètre div. De là, le drill down peut continuer avec le résultat attendu.
Le comportement du code original peut utiliser un peu plus d'explication. Lorsqu'une propriété est accessible sur une Liste en Groovy, vous aurez une nouvelle liste (même taille) avec la propriété de chaque élément dans la liste. La liste qui se trouve par grep() n'a qu'une seule entrée. Puis, nous avons une entrée de la propriété ol, ce qui est bien. Ensuite, nous obtenons le résultat de l'ol.pour cette entrée. C'est une liste de size() == 1 nouveau, mais cette fois avec une entrée de taille() == 2. Nous pourrions appliquer la boucle externe là-bas et obtenir le même résultat, si l'on voulait:
Sur toute GPathResult représentant plusieurs nœuds, nous obtenons la concaténation de tous les textes. C'est le résultat original, d'abord pour @href, puis pour adresse.
OriginalL'auteur eddelplus
Je crois que les réponses précédentes sont correctes au moment de la rédaction de la version utilisée. Mais je suis en utilisant HTTPBuilder 0.7.1 et Graal 2.4.4 avec Groovy 2.3.7 et il y a un gros problème - éléments HTML sont transformées en majuscules. Il semble que cela est dû à NekoHTML utilisé sous le capot:
http://nekohtml.sourceforge.net/faq.html#uppercase
De ce fait, la solution dans l'acceptation de la réponse doit être écrite comme suit:
Cela a été très frustrant pour déboguer, espérons que cela aide quelqu'un.
OriginalL'auteur Philip