【问题标题】:XPath to pick an element based on the text in parent or any of its childXPath 根据父级或其任何子级中的文本选择元素
【发布时间】:2018-12-09 19:58:42
【问题描述】:

如果该元素或任何一个子元素具有特定文本,是否有办法选择该元素?

例如,这里有两个例子:

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

【问题讨论】:

    标签: html xpath


    【解决方案1】:

    有没有更好的 XPath 来根据父级或任何子级中的文本来选择 div?

    使用.,而不是text()

    //*[contains(., 'Tag 1')]
    

    text() 不会给你元素的“文本”。

    它为您提供了一个 文本节点 的列表 (!),它们是当前上下文节点的直接子节点。当上下文节点在示例 #2 中为 &lt;div&gt; 时,该列表将是三个仅包含空格的文本节点。我用括号突出显示了它们:

    <div title='Title2'>[
      ]<input type='checkbox' />[
      ]<span>Tag 1<span>[
    ]</div>
    

    'Tag 1'&lt;span&gt; 的子代,而不是 &lt;div&gt; 的子代。

    现在,contains() 不接受节点列表。如果你给它一个节点列表,它只会考虑该列表中第一个节点的字符串值。节点的字符串值是它包含的所有文本节点的串联,而不仅仅是直接子节点。

    . 指上下文节点。在示例 #2 中,这就是 &lt;div&gt; 本身。 contains() 再次将其转换为字符串,但这一次,该字符串实际上包含 Tag 1。另一种写法是:

    //*[contains(string(.), 'Tag 1')]
    

    这就是你认为text() 会做的事情。

    现在//* 是递归的,这意味着将选择&lt;div&gt;&lt;span&gt; 和所有&lt;div&gt; 祖先,因为它们都包含Tag 1

    使用比//* 更具体的东西来解决这个问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-04-03
      • 1970-01-01
      • 1970-01-01
      • 2017-02-24
      • 1970-01-01
      • 2023-03-04
      相关资源
      最近更新 更多