XPath 中的 contains() 有什么作用? [英] What does contains() do in XPath?
问题描述
我有两个几乎相同的表,唯一的区别是第一个中的输入标签:
表 #1
<tr><td><div><input type="text" name="" value=""/></td></tr></tbody>
表 #2
<tr><td><div></div></td></tr></tbody>
我有两个几乎相同的表,唯一的区别是第一个中的输入标签:
表 #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 中:
contains()
不检查元素遏制.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:
contains()
does not check for element
containment.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屋!