1

我在构建一个查询时遇到了很多困难,该查询将在一个字符串中返回来自以下所有元素的所有文本(假设页面上的所有其他元素也包含文本并且不是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

4 回答 4

1

Xpath 1.0 函数确实适用于字符串 -而normalize-space()不是节点集。在您的示例代码中,您有一个节点集作为它的第一个参数:

 normalize-space(//*/div | //*/span)

在这种情况下,“节点集的字符串值”是第一个节点的字符串值。因此,您所做的不适合您的需求。

据我所知,仅使用单个 XPath 1.0 查询是不可能实现您正在寻找的。可以在 PHP 的帮助下创建您要查找的字符串,方法是注册一个 PHP 函数来执行您要查找的操作。

另见:

于 2013-07-22T15:04:20.357 回答
1

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

normalize-space(.)
于 2013-07-17T14:02:19.520 回答
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'
>>> 
于 2013-07-17T13:45:26.580 回答
0

这适用于 xpath 2.0:

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

在这里测试,打印:

Hello World !!! This is cool
于 2013-07-17T13:27:37.307 回答