如果该元素或子元素中的任何一个具有特定文本,是否可以选择一个元素?
例如,以下是两个示例:
示例1:
<div title='Title1'>
<input type='checkbox'>
"Tag 1"
</div>
示例2:
<div title='Title2'>
<input type='checkbox'>
<span>Tag 1<span>
</div>
无论文本是否在范围内,我都希望选择标记div。
但是下面的XPath为第二种情况选择了标签范围。
//*[(contains(text(), 'Tag 1'))]
是否有更好的XPath根据父级或子级中的文本选择div?
答案 0 :(得分:1)
是否有更好的XPath根据父级或子级中的文本选择div?
使用.
,而不是text()
。
//*[contains(., 'Tag 1')]
text()
没有给您元素的“文本”。
它为您提供了文本节点的列表(!),它们是当前上下文节点的直接子代。在示例#2中,上下文节点为<div>
时,该列表将是三个仅包含空格的文本节点。我用方括号突出显示了它们:
<div title='Title2'>[
]<input type='checkbox' />[
]<span>Tag 1<span>[
]</div>
'Tag 1'
是<span>
的子级,而不是<div>
的子级。
现在,contains()
不接受节点列表。如果给它一个节点列表,它将只考虑该列表中第一个节点的 string值。节点的字符串值是它包含的所有文本节点的串联,而不仅仅是直接子节点。
.
指上下文节点。在示例2中,它就是<div>
本身。 contains()
再次将其转换为字符串,但是这次,该字符串实际上包含Tag 1
。另一种写法是:
//*[contains(string(.), 'Tag 1')]
这就是您认为text()
会做的。
现在//*
是递归的,这意味着<div>
,<span>
和所有<div>
的祖先也会被选中,因为它们都包含{{1} }。
使用比Tag 1
更具体的内容来解决此问题。