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

Posted

技术标签:

【中文标题】如何在这里使用 XPath contains()?【英文标题】:How to use XPath contains() here? 【发布时间】:2010-11-07 02:09:05 【问题描述】:

我正在努力学习 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>
...

【问题讨论】:

这对我有用,我在whitebeam.org/library/guide/TechNotes/xpathtestbed.rhtm上测试过 【参考方案1】:

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

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

此查询将为您提供具有 classfeatureList 的元素以及一个或多个包含文本 'Model'li 子元素。

【讨论】:

+1 -- "./" 有点误导——它表明当你把它排除在外时,除了当前节点之外的任何东西都会被考虑在内,但实际上它是多余的:" //ul[@class='featureList' 和 li[contains(.,'Model')]]" 是一回事。 是的,我只是说具体点。很可能过于具体。 如果ul 中没有liModel,则and 条件将失败。那么and 条件在空集上返回false,对吗?【参考方案2】:

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

以下是您的方法不起作用的快速解释。这个:

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

遇到contains() 函数(或XPath 中的任何其他字符串函数,就此而言)的限制。

第一个参数应该是一个字符串。如果你给它一个节点列表(给它“li”这样做),必须进行到字符串的转换。但是这种转换仅针对列表中的第一个节点进行。

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

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

实际上会选择一个节点!

【讨论】:

很好的人一直在努力弄清楚为什么像这样的查询:“.//td[contains(.//*,'something')]”只能工作到 1 的深度。我想了解如何使其工作,但不确定上述内容是如何工作的。我真正需要的是 ".//td[.//*[contains(.,'something')]]"【参考方案3】:

这是对关于 XPath 中的contains()常见误解老问题的新答案...

总结:contains() 表示包含子串 包含节点

详细说明

这个 XPath 经常被误解:

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

错误解释: 选择那些 包含 li 元素和 Modelul 元素。

这是错误的,因为

    contains(x,y) 期望 x 是一个字符串,并且 将多个元素转换为字符串的 XPath 规则是 this:

通过返回string-value 将节点集转换为字符串 document order 中的第一个节点集中的节点。如果 节点集为空,返回一个空字符串。

正确解释: 选择那些 first li 子元素具有 string-valueul 元素 包含一个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 ul 中的Foo 不包含Model 子串。

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

注意:两个ul 元素都被选中,因为contains() 分别应用于每个li。 (因此,避免了棘手的多元素到字符串的转换规则。)两个ul 元素确实都有一个li 子元素,其字符串值包含Model 子字符串——li 元素的位置不再很重要。

另见

Testing text() nodes vs string values in XPath

【讨论】:

【参考方案4】:
//ul[@class="featureList" and li//text()[contains(., "Model")]]

【讨论】:

【参考方案5】:

在此处粘贴我的 contains 示例:

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

【讨论】:

OP 的代码中没有 table 元素或 EC_result 类值。 这个答案在这里没有意义,应该删除。

以上是关于如何在这里使用 XPath contains()?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 PHP 中使用 XPath 设置 (not(contains))

如何在 XPath 中使用 not contains()?

如果搜索参数为空白或缺失/错误,我如何使用 Xpath 函数“contains()”不返回任何内容?

如何在 XPath“包含”函数中使用正则表达式

XPath 通配符和 contains() 函数用法

如何在 C# 中使用 XPath 包含