我对此问题有一个后续问题:Groovy XmlSlurper get value of the node without children。
它解释了为了获得(HTML)节点的本地内部文本而不递归地获取潜在内部子节点的嵌套文本,必须使用#localText()
而不是#text()
例如,原始问题的一个稍微增强的例子:
<html>
<body>
<div>
Text I would like to get1.
<a href="http://intro.com">extra stuff</a>
Text I would like to get2.
<a href="http://example.com">link to example</a>
Text I would like to get3.
</div>
<span>
<a href="http://intro.com">extra stuff</a>
Text I would like to get2.
<a href="http://example.com">link to example</a>
Text I would like to get3.
</span>
</body>
</html>
应用解决方案:
def tagsoupParser = new org.ccil.cowan.tagsoup.Parser()
def slurper = new XmlSlurper(tagsoupParser)
def htmlParsed = slurper.parseText(stringToParse)
println htmlParsed.body.div[0].localText()[0]
将返回:
[Text I would like to get1., Text I would like to get2., Text I would like to get3.]
但是,解析此示例中的<span>
部分
println htmlParsed.body.span[0].localText()
输出
[Text I would like to get2., Text I would like to get3.]
我现在面临的问题是,显然无法确定文本的位置(“在哪个子节点之间”)。我本来期望第二次调用产生
[, Text I would like to get2., Text I would like to get3.]
这可以说清楚:位置0(在孩子0之前)是空的,位置1(在孩子0和1之间)是“文本我想得到2”。和位置2(在孩子1和2之间)是“我希望获得的文字3”。但是,鉴于API的工作原理,显然无法确定在索引0处返回的文本是否实际位于索引0或任何其他索引处,并且对于所有其他索引也是如此。
我已经使用XmlSlurper
和XmlParser
进行了尝试,结果相同。
如果我没有弄错,那么使用解析器中的信息完全重新创建原始HTML文档也是不可能的,因为这个“文本索引”信息会丢失。
我的问题是:有没有办法找出这些文字位置?要求我更改解析器的答案也是可以接受的。
更新/解决方案:
为了进一步参考,这里是Will P的答案,适用于原始代码:
def tagsoupParser = new org.ccil.cowan.tagsoup.Parser()
def slurper = new XmlParser(tagsoupParser)
def htmlParsed = slurper.parseText(stringToParse)
println htmlParsed.body.div[0].children().collect {it in String ? it : null}
这会产生:
[Text I would like to get1., null, Text I would like to get2., null, Text I would like to get3.]
必须使用 XmlParser
代替 XmlSlurper
和node.children()
。
答案 0 :(得分:1)
我不知道jsoup,我希望它不会干扰解决方案,但是使用纯XmlParser
,你可以得到一个包含原始字符串的children()
数组:
html = '''<html>
<body>
<div>
Text I would like to get1.
<a href="http://intro.com">extra stuff</a>
Text I would like to get2.
<a href="http://example.com">link to example</a>
Text I would like to get3.
</div>
<span>
<a href="http://intro.com">extra stuff</a>
Text I would like to get2.
<a href="http://example.com">link to example</a>
Text I would like to get3.
</span>
</body>
</html>'''
def root = new XmlParser().parseText html
root.body.div[0].children().with {
assert get(0).trim() == 'Text I would like to get1.'
assert get(0).getClass() == String
assert get(1).name() == 'a'
assert get(1).getClass() == Node
assert get(2) == '''
Text I would like to get2.
'''
}