Groovy Knoten.depthFirst() Rückgabe einer Liste von Knoten und Fäden?
Ich hoffe jemand wird nur etwas zeigen offensichtlich, dass ich hier vermisst. Ich fühle mich wie ich getan habe, das hundert mal und aus irgendeinem Grund heute Abend, das Verhalten aus dieser wirft mich für eine Schleife.
Lese ich in einigen XML-Daten von einer öffentlichen API. Ich möchte alle extrahieren Sie den text aus einem bestimmten Knoten (alles innerhalb von 'Körper'), die auch eine Vielzahl von untergeordneten Knoten. Einfaches Beispiel:
<xml>
<metadata>
<article>
<body>
<sec>
<title>A Title</title>
<p>
This contains
<italic>italics</italic>
and
<xref ref-type="bibr">xref's</xref>
.
</p>
</sec>
<sec>
<title>Second Title</title>
</sec>
</body>
</article>
</metadata>
</xml>
Also letztendlich will ich die traverse den Baum in der gewünschten Knoten (wieder, 'Körper'), und extrahieren Sie alle Texte, die in Ihrer natürlichen Ordnung. Einfach genug, also schreib ich einfach dieses kleine Groovy-Skript...
def xmlParser = new XmlParser()
def xml = xmlParser.parseText(rawXml)
xml.metadata.article.body[0].depthFirst().each { node ->
if(node.children().size() == 1) {
println node.text()
}
}
...die Erlöse zu Blasen, bis mit "No signature of method: java.lang.String.(Kinder)". Also dachte ich mir "warte, was? Bin ich verrückt?" Knoten.depthFirst() sollte nur zurückgeben einer Liste von Knoten ist. Ich fügen Sie ein wenig 'instanceof' überprüfen, und sicher genug, ich bin immer eine Kombination von Node-Objekten und String-Objekte. Speziell die Zeilen, die nicht innerhalb der Entitäten auf der gleichen Zeile werden als String zurückgegeben ist, aka "Das enthält" und "und". Alles andere ist ein Knoten (wie erwartet).
Kann ich arbeiten, um dieses leicht. Jedoch, dies scheint nicht korrekt Verhalten und ich bin der Hoffnung, jemand kann mich in die richtige Richtung.
- Soweit ich das beurteilen kann, Knoten.depthFirst verhielt sich so, als würden Sie erwarten, dass in groovy 1.7. In groovy 2.0+, sehe ich die gleichen Ergebnisse von Knoten/Strings.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ich bin mir ziemlich sicher, dass das richtige Verhalten (obwohl ich schon immer fand das XmlSlurper und XmlParser zu haben screwy APIs). Alle Dinge, die Sie Durchlaufen sollte wirklich realisieren ein Knoten-Schnittstelle und IMO potentiell zu einem
type
vonTEXT
, das Sie verwenden können, um zu wissen, um den text von Ihnen.Diese text-Knoten gültig sind Knoten, die in vielen Fällen würden Sie wollen, zu schlagen, als es hat eine Tiefe ersten Durchlauf durch die XML. Wenn Sie nicht das bekommen haben, zurückgegeben, den Algorithmus für die überprüfung, ob die Kinder Größe von 1 würde nicht funktionieren, weil einige Knoten (wie die
<p>
tag) hat die beiden gemischten text und Elemente darunter.Auch, warum
depthFirst
nicht konsequent Rückgabe aller text-Knoten, wo der text ist das einzige Kind, wie füritalic
oben, macht die Sache nur noch schlimmer.Tendiere ich zu gerne die Signatur von groovy-Methoden zu lassen, die Laufzeit herauszufinden, welche ist die richtige Methode zum behandeln von jedem Knoten (eher als mit so etwas wie
instanceof
) wie folgt:Drucke
Alternativ die
XmlSlurper
Klasse wohl nicht mehr, was Sie wollen/erwarten, dass es mehr angemessenen Satz der Ausgabe vontext()
Methode. Wenn Sie wirklich brauchen nicht zu tun, jede Art von DOM zu Fuß mit den Ergebnissen (wasXmlParser
ist "besser" für), würde ich vorschlagen, dassXmlSlurper
:Drucke:
depthFirst()