我有两个几乎相同的表,唯一的区别是第一个中的输入标记:
表格1
<table> <tbody> <tr> <td> <div> <input type="text" name="" value=""/> </div> </td> </tr> </tbody> </table>
表#2
<table> <tbody> <tr> <td> <div></div> </td> </tr> </tbody> </table> </body>
当我使用这个XPath //表// tbody // tr [position()= 1并包含(.,input)]时,它返回两个表的第一行,而不仅仅是我期望的第一个表第一行.
但是,此XPath //表// tbody // tr [position()= 1] //输入仅返回第一个输入.
那么,我做错了什么?为什么相同的输入与两个表相关联?我是否滥用了.不知怎的?
解决方法
由于功能名称1的不幸选择,很多人误以为XPath中
contains()
功能的用途:
> XPath contains()不检查元素
遏制.
> XPath contains()检查子字符串包含.
因此,tr [contains(.,input)]不会按照您的想法执行.它实际上选择了tr个元素,其中string-value包含的子字符串等于第一个直接子输入元素的字符串值;有关详细信息,请参阅this answer. (有趣的是,这样的谓词简化为true,因为字符串值定义的分层特性意味着父元素和子元素的字符串值之间的子字符串包含.)无论如何,这显然不是你的意图.
要检查后代元素包含,请改用.//input.这可以作为第一个XPath尝试执行的tr的谓词,如果它是你想要选择的tr元素,
//table//tbody//tr[position()=1 and .//input]
或表(as shown by @Andersson),如果它是您想要选择的包含输入后代元素的表元素:
//table[.//input]
为什么XPath contains()应该被命名为string-contains()
1在XML的上下文中,它强烈地基于层次结构的概念,很自然地假设contains是指层次包含.在最初的XPath规范中,单词包含的24次出现,其中19次表示分层节点包含;只有5次意味着子串遏制.毫无疑问,contains()存在混淆. XPath子串contains()函数应该已经命名为string-contains().