我在构建一个查询时遇到很多困难,该查询将返回一个字符串中所有下面元素的所有文本(假设页面上的所有其他元素也包含文本而不是span
或div
元素)。
注意:因为我使用的是PHP XPath引擎,所以我不得不使用XPath 1.0的解决方案。
HTML
<div>Hello</div>
<div>World</div>
<div>!!!</div>
<span>This</span>
<span>is</span>
<span>cool</span>
的XPath
normalize-space(//*/div | //*/span)
期望的输出:
Hello World!!! This is cool
我感谢任何建议。非常感谢提前!
答案 0 :(得分:1)
元素之间已经有空格,因此无需添加任何元素,只要将其包含在您选择的内容中即可。如果将节点集传递给需要字符串的节点,则XPath将节点集转换为字符串,只需按文档顺序将所有后代文本节点连接在一起即可。因此,如果上下文节点是所有这些div
和span
元素的父元素,那么最简单的表达式就是
normalize-space(.)
答案 1 :(得分:1)
normalize-space()
Xpath 1.0函数对字符串起作用 - 而不是在节点集上。在您的示例代码中,您有一个节点集作为它的第一个参数:
normalize-space(//*/div | //*/span)
在这种情况下,"string-value of a node-set"是第一个节点的字符串值。所以你做的不适合你的需要。
据我所知,使用单个XPath 1.0查询单独无法实现您所需要的功能。在PHP的帮助下,可以通过注册一个能够满足您需求的PHP函数来创建您正在寻找的字符串。
参见:
答案 2 :(得分:0)
答案 3 :(得分:0)
在lxml(Python)中使用EXSLT字符串扩展 http://www.exslt.org/str/str.html
str:replace(str:concat(//text()), "\n", " ")
甚至更简单
normalize-space(str:concat(//text()))
在Python shell中测试
>>> import lxml.etree
>>> import lxml.html
>>> doc="""<div>Hello</div>
... <div>World</div>
... <div>!!!</div>
... <span>This</span>
... <span>is</span>
... <span>cool</span>"""
>>> root = lxml.etree.fromstring(doc, parser=lxml.html.HTMLParser())
>>> root.xpath('str:replace(str:concat(//text()), "\n", " ")', namespaces={"str": "http://exslt.org/strings"})
'Hello World !!! This is cool'
>>> root.xpath('normalize-space(str:concat(//text()))', namespaces={"str": "http://exslt.org/strings"})
'Hello World !!! This is cool'
>>>