Mit XmlSlurper: Wie wählen Sie die sub-Elemente während der Iteration über eine GPathResult
Schreibe ich ein HTML-parser, die verwendet TagSoup passieren eine wohlgeformte Struktur zu XMLSlurper.
Hier ist der verallgemeinerte 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"
}
Ich würde erwarten, dass die einzelnen, lassen Sie mich wählen Sie die einzelnen 'li' in umdrehung, so kann ich abrufen die entsprechende href-und Adressdaten. Stattdessen erhalte ich diese Ausgabe:
#href1#href2: Here is the addressTelephone number: telephoneHere is another addressAnother telephone: 0845 1111111
Ich habe verschiedene Beispiel auf der web-und diese entweder Umgang mit XML, oder sind one-liner Beispiele wie "abrufen alle links aus dieser Datei". Es scheint, dass die it.h3.a.@href Ausdruck sammeln alle hrefs in den text, obwohl ich die übergabe einer Referenz auf das parent - 'li' - Knoten.
Können Sie lassen Sie mich wissen:
- Warum bin ich immer die gezeigte Ausgabe
- Wie kann ich abrufen die href - /Adress-Paare für jeden 'li' - Element
Dank.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ersetzen mit grep finden:
dann erhalten Sie
grep ein ArrayList gibt, finden aber gibt eine NodeChild Klasse:
Ergebnisse in:
so, wenn Sie wollten, um mit grep könntest du dann ein anderes nest jeweils, wie dies für ihn zu arbeiten
Lange Geschichte kurz, in Ihrem Fall, verwenden Sie finden statt grep.
War dies ist eine knifflige Sache. Wenn es nur ein element mit class='divclass" die Vorherige Antwort ist sicher in Ordnung. Wenn es mehrere Ergebnisse von grep, dann find() für ein Ergebnis ist nicht die Antwort. Wies darauf hin, dass das Ergebnis in eine ArrayList ist richtig. Einfügen eines äußeren verschachtelt .each () - Schleife stellt eine GPathResult, die in der Schließung parameter div. Von hier aus der drill-down-kann weiterhin mit dem erwarteten Ergebnis.
Dem Verhalten der original-code verwenden können, ein bisschen mehr von einer Erklärung als gut. Wenn eine Eigenschaft zugegriffen wird, die auf einer Liste in Groovy, erhalten Sie eine neue Liste (gleiche Größe) mit der Eigenschaft für jedes element in der Liste. Die Liste von grep() hat nur einen Eintrag. Dann bekommen wir einen Eintrag für die Eigenschaft ol, was in Ordnung ist. Weiter erhalten wir das Ergebnis von ol.es für diesen Eintrag. Es ist eine Liste von size() == 1 wieder, aber dieses mal mit einem Eintrag von size() == 2. Wir könnten die äußere Schleife dort und das gleiche Ergebnis erhalten, wenn wir das wollten:
Auf jeden GPathResult stellvertretend für mehrere Knoten, so erhalten wir die Verkettung des gesamten Textes. Das ist das ursprüngliche Ergebnis, zunächst für @href, dann für Adresse.
Ich glaube, die bisherigen Antworten sind alle richtig, die Zeit zu schreiben, für die verwendete version. Aber ich bin mit HTTPBuilder 0.7.1-und Grails-2.4.4 mit Groovy 2.3.7 und es ist ein großes Problem - HTML-Elemente transformiert werden zu Großbuchstaben. Es scheint dies aufgrund von NekoHTML verwendet unter der Haube:
http://nekohtml.sourceforge.net/faq.html#uppercase
Weil dieses, die Lösung in der akzeptierten Antworten müssen geschrieben werden als:
War dies sehr frustrierend, zu Debuggen, hoffe, es hilft jemand.