如何在这里使用XPath contains()?


142

我正在尝试学习XPath。我在contains()这里查看了其他示例,但没有使用AND运算符的示例。我无法使它正常工作:

//ul[@class='featureList' and contains(li, 'Model')]

上:

...
<ul class="featureList">

<li><b>Type:</b> Clip Fan</li><li><b>Feature:</b> Air Moved: 65 ft.
    Amps: 1.1
    Clip: Grips any surface up to 1.63"
    Plug: 3 prong grounded plug on heavy duty model
    Usage: Garage, Workshop, Dorm, Work-out room, Deck, Office & more.</li><li><b>Speed Setting:</b> 2 speeds</li><li><b>Color:</b> Black</li><li><b>Power Consumption:</b> 62 W</li><li><b>Height:</b> 14.5"</li><li><b>Width:</b> Grill Diameter: 9.5"</li><li><b>Length:</b> 11.5"</li>

<li><b>Model #: </b>CR1-0081-06</li>
<li><b>Item #: </b>N82E16896817007</li>
<li><b>Return Policy: </b></li>
</ul>
...

这对我有用
mihi,2009年

Answers:


199

您只查看li查询中的第一li个子元素,而不是查找可能包含文本的任何子元素'Model'。您需要的是类似以下的查询:

//ul[@class='featureList' and ./li[contains(.,'Model')]]

该查询会给你有一个元素classfeatureList一个或多个li包含文本的孩子,'Model'


13
+1-“ ./”有点误导-它表示当您忽略它时,将考虑当前节点以外的任何其他内容,但实际上它是多余的:“ // ul [@ class =' featureList'和li [contains(。,'Model')]]“”是同一件事。
Tomalak

4
是的,我只是很具体。可能过于具体。
Jeff Yates

如果in中没有liwith ,那么条件将失败。因此条件返回空集,对吗?Modelulandandfalse
damluar 2014年

58

我已经给Jeff Yates的解决方案+1了。

这里是一个简短的解释,为什么您的方法不起作用。这个:

// ul [@ class ='featureList'和contains(li,'Model')]

遇到contains()函数的限制(或者XPath中的任何其他字符串函数)。

第一个参数应该是字符串。如果您向它提供节点列表(给它做“ li”),则必须进行字符串转换。但是,此转换仅针对列表中的第一个节点完成。

在您的情况下,列表中的第一个节点是<li><b>Type:</b> Clip Fan</li>(转换为字符串:“ Type: Clip Fan”),这意味着:

// ul [@ class ='featureList'和contains(li,'Type')]

实际上会选择一个节点!


1
很好的人一直在努力弄清楚为什么这样的查询:“ .//td[contains(.//*,'something')]”只能工作到1的深度。确保以上内容是如何工作的。我真正需要的是“ .//td[.//*[contains(.,'something')]]”“
JonnyRaa 2014年

11

这是有关contains()XPath中常见误解的旧问题的新答案。

摘要:contains()意味着包含一个子字符串而不 包含一个node

详细说明

该XPath通常被误解为:

//ul[contains(li, 'Model')]

错误的解释: 选择那些ul的元素包含li元素与Model它。

这是错误的,因为

  1. contains(x,y)期望x是一个字符串,并且
  2. 用于将多个元素转换为字符串的XPath规则是这样的

    通过返回节点集中按文档顺序首先出现的节点的字符串值,可以将节点集转换为字符串。如果节点集为空,则返回一个空字符串。

正确的解释:选择那些ul其元素第一 li的孩子有一个字符串值,包含一个Model字符串。

例子

XML格式

<r>
  <ul id="one">
    <li>Model A</li>
    <li>Foo</li>
  </ul>
  <ul id="two">
    <li>Foo</li>
    <li>Model A</li>
  </ul>
</r> 

XPaths

  • //ul[contains(li, 'Model')]选择one ul元素。

    注:two ul没有选择元素,因为第一个字符串值li的孩子two ulFoo,其中不包含Model子。

  • //ul[li[contains(.,'Model')]]选择onetwo ul元素。

    注意:ul选择这两个元素是因为contains()它们li分别应用于每个元素。(因此,避免了棘手的将多个元素转换为字符串的规则。)两个ul元素的确都有一个li孩子,其子字符串值包含Model子字符串- li元素的位置不再重要。

也可以看看


-2
//ul[@class="featureList" and li//text()[contains(., "Model")]]

-5

contains在此处粘贴我的示例:

//table[contains(@class, "EC_result")]/tbody

2
OP的代码中没有table元素或EC_result类的值。 这个答案在这里没有意义,应该删除。
kjhughes
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.