我很确定这是正确的行为(尽管我总是发现 XmlSlurper 和 XmlParser 有奇怪的 API)。在我看来,所有你可以迭代的东西都应该实现一个节点接口,并且可能有一个type
of TEXT
您可以用它来了解从他们那里获取文本。
这些文本节点是有效节点,在许多情况下您希望在它对 XML 进行深度优先遍历时命中它们。如果它们没有返回,则用于检查子节点大小是否为 1 的算法将不起作用,因为某些节点(例如<p>
标签)下面有混合文本和元素。
还有,为什么depthFirst
并不始终返回文本是唯一子节点的所有文本节点,例如 foritalic
上面,让事情变得更糟。
我倾向于使用常规方法的签名来让运行时找出处理每个节点的正确方法(而不是使用类似的方法)instanceof
) 像这样:
def rawXml = """<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>"""
def processNode(String nodeText) {
return nodeText
}
def processNode(Object node) {
if(node.children().size() == 1) {
return node.text()
}
}
def xmlParser = new XmlParser()
def xml = xmlParser.parseText(rawXml)
def xmlText = xml.metadata.article.body[0].'**'.findResults { node ->
processNode(node)
}
println xmlText.join(" ")
Prints
A Title This contains italics and xref's . Second Title
或者,XmlSlurper
类可能会做更多你想要/期望的事情,并且有一组更合理的输出text()
方法。如果你真的不需要对结果进行任何类型的 DOM 遍历(什么XmlParser
是“更好”),我建议XmlSlurper
:
def xmlParser = new XmlSlurper()
def xml = xmlParser.parseText(rawXml)
def bodyText = xml.metadata.article.body[0].text()
println bodyText
Prints:
A Title
This contains
italics
and
xref's
.
Second Title