xpath normalize-space与contains

时间:2018-11-09 16:29:11

标签: xpath

我有一个xpath字符串//*[normalize-space() = "some sub text"]/text()/..,如果我找到的文本在一个没有多个文本子节点的节点中,则可以正常工作,但是如果这样做,它将无法正常工作,所以我正在尝试将其与contains()组合如下://*[contains(normalize-space(), "some sub text")]/text()/..确实有效,但是它总是返回bodyhtml标签以及包含以下内容的p标签文本。如何更改它,使其仅返回p标记?

1 个答案:

答案 0 :(得分:1)

这完全取决于您要匹配的内容。

最可能的情况是,如果some text出现在元素的规范化字符串值中的任何位置,并且可能分散在不同级别的多个文本节点上,则要进行匹配:例如以下任意一项:

<p>some text</p>
<p>There was some text</p>
<p>There was <b>some text</b></p>
<p>There <b>was</b> some text</p>
<p>There was <b>some</b> <!--italic--> <i>text</i></p>
<p>There was <b>some</b> text</p>

如果是这种情况,请使用//p[contains(normalize-space(.), "some text")]

如您所指出的,将//*与该谓词一起使用还将匹配相关元素的祖先元素。解决此问题的最简单方法是使用//p说出您要查找的元素。如果您不知道要寻找什么元素,则可以在XPath 3.0中使用

innermost(//*[contains(normalize-space(.), "some text")])

但是如果您不幸没有使用XPath 3.0,则可以执行(//*[contains(normalize-space(.), "some text")])[last()],尽管如果有多个具有所需内容的段落,这样做的效果就不一样。

如果您不想同时满足以上所有条件,但希望更具选择性,那么您需要更清楚地说明您的要求。

无论哪种方式,通常在路径表达式中使用text()都是一种代码味道,除非在极少数情况下,仅当元素没有被其他标签包裹时,才希望在元素中选择文本。