XPath根据父级或其任何子级中的文本选择元素

时间:2018-07-01 08:51:54

标签: html xpath

如果该元素或子元素中的任何一个具有特定文本,是否可以选择一个元素?

例如,以下是两个示例:

示例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?

1 个答案:

答案 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更具体的内容来解决此问题。