XPath 中的 contains() 有什么作用? [英] What does contains() do in XPath?

查看:27
本文介绍了XPath 中的 contains() 有什么作用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两个几乎相同的表,唯一的区别是第一个中的输入标签:

表 #1

 <tr><td><div><input type="text" name="" value=""/>

</td></tr></tbody>

表 #2

 <tr><td><div></div></td></tr></tbody>

当我使用这个 XPath //table//tbody//tr[position()=1 and contains(.,input)] 它返回两个表的第一行,而不仅仅是第一行如我所料,表第一行.

然而,这个 XPath //table//tbody//tr[position()=1]//input 只返回第一个中的 input.

那么,我做错了什么?为什么相同的 input 与两个表相关联?我是否以某种方式滥用了 . ?

解决方案

由于不幸的函数名称选择1,很多人误解了contains() 函数在 XPath 中:

  • XPath contains()检查元素遏制.
  • XPath contains() 检查 substring 是否包含.

因此,tr[contains(.,input)] 并没有像你想象的那样做.它实际上选择 tr 元素,其 string-value 包含等于第一个直接子 input 元素的 string-value 的子字符串;有关更多详细信息,请参阅此答案.(有趣的是,这样的谓词简化为 true,因为 string-value 定义的分层性质意味着父元素和子元素的字符串值之间的子字符串包含.)无论如何,这显然不是您的意图.

要检查后代元素是否包含,请改用.//input.这可以作为 tr 的谓词作为您的第一个 XPath 尝试执行的操作,如果您希望选择 tr 元素,

//table//tbody//tr[position()=1 and .//input]

table(如@Andersson 所示),如果它真的是 您希望选择包含 input 后代元素的 table 元素:

//table[.//input]

<小时>

为什么 XPath contains() 应该被命名为 string-contains()

1在强烈基于层次概念的 XML 上下文中,很自然地假设 contains 指的是层次包含.contains 出现在原始 XPath 规范中的 24 次中,19 次表示分层节点包含;只有 5 次才意味着包含子串.难怪对 contains() 存在混淆.XPath 子字符串 contains() 函数应该被命名为 string-contains().

I have two almost identical tables, the only difference being the input tag in the first one:

Table #1

  <table>
    <tbody>
      <tr>
        <td>
          <div>
            <input type="text" name="" value=""/>
          </div>
        </td>
      </tr>
    </tbody>
  </table>

Table #2

  <table>
    <tbody>
      <tr>
        <td>
          <div></div>
        </td>
      </tr>
    </tbody>
  </table>
</body>

When I use this XPath //table//tbody//tr[position()=1 and contains(.,input)] it returns both tables' 1st row, not just the 1st table 1st row as I expect.

However, this XPath //table//tbody//tr[position()=1]//input returns just the input in the first one.

So, what am I doing wrong? Why the same input is associated with both tables? Am I misusing the . here somehow?

解决方案

Due to an unfortunate choice in function names1, many people mistake the purpose of the contains() function in XPath:

  • XPath contains() does not check for element containment.
  • XPath contains() checks for substring containment.

Therefore, tr[contains(.,input)] doesn't do what you think it does. It actually selects tr elements whose string-value contains a substring equal to the string-value of the first immediate child input element; see this answer for further details. (Interestingly, such a predicate simplifies to true because the hierarchical nature of the definition of string-value implies substring containment between string values of parent and child elements.) Anyway, that's clearly not your intent.

To check for descendant element containment, use .//input instead. This can be placed as a predicate of tr as your first XPath attempted to do, if it's tr elements that you wish to select,

//table//tbody//tr[position()=1 and .//input]

or table (as shown by @Andersson), if it's really table elements that you wish to select that contain an input descendant element:

//table[.//input]


Why XPath contains() should have been named string-contains()

1In the context of XML, which is so strongly based upon the notion of hierarchy, it is natural to assume that contains refers to hierarchical containment. Of the 24 times the word contains appears in the original XPath specification, 19 times it means hierarchical node containment; only 5 times does it mean substring containment. It's no wonder that confusion over contains() exists. The XPath substring contains() function should have been named string-contains().

这篇关于XPath 中的 contains() 有什么作用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆