XPath从与XPath查询匹配的所有元素中获取文本

时间:2013-07-17 13:12:36

标签: php xpath

我在构建一个查询时遇到很多困难,该查询将返回一个字符串中所有下面元素的所有文本(假设页面上的所有其他元素也包含文本而不是spandiv元素)

注意:因为我使用的是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

我感谢任何建议。非常感谢提前!

4 个答案:

答案 0 :(得分:1)

元素之间已经有空格,因此无需添加任何元素,只要将其包含在您选择的内容中即可。如果将节点集传递给需要字符串的节点,则XPath将节点集转换为字符串,只需按文档顺序将所有后代文本节点连接在一起即可。因此,如果上下文节点是所有这些divspan元素的父元素,那么最简单的表达式就是

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)

这适用于xpath 2.0:

string-join(/*/text(), ' ')

经过测试here,打印:

Hello World !!! This is cool

答案 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'
>>>