我有一个xpath字符串//*[normalize-space() = "some sub text"]/text()/..
,如果我找到的文本在一个没有多个文本子节点的节点中,则可以正常工作,但是如果这样做,它将无法正常工作,所以我正在尝试将其与contains()
组合如下://*[contains(normalize-space(), "some sub text")]/text()/..
确实有效,但是它总是返回body
和html
标签以及包含以下内容的p
标签文本。如何更改它,使其仅返回p
标记?
答案 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()
都是一种代码味道,除非在极少数情况下,仅当元素没有被其他标签包裹时,才希望在元素中选择文本。