使用XPath获取节点的每个子节点的第一个子节点

时间:2016-02-23 19:57:04

标签: html xpath

我尝试使用以下结构解析一些HTML,如何使用xpath提取每个<a>元素的第一个<li>元素?

<ul>
    <li>
        <a>
        <span>
        <a>
    </li>
    <li>
        <a>
        <span>
        <a>
    </li>
    ...
</ul>

2 个答案:

答案 0 :(得分:4)

  

@Mathias:你是对的,我道歉。 // li / a [1]不起作用,因为它不是直接的孩子(中间有一个文章标签,为简单起见我省略了。)

然后让我发布这个解决方案,并提供更多解释。

如果如您所述,//li/a[1](//li//a)[1]执行时未返回任何内容,则您显示的HTML示例不代表您的实际文档。然后,a将是li的后代,但不是它的直系子女。

在这种情况下,正确的XPath表达式是

//li//a[1]

但只有在嵌套级别不同时才使用它,即如果lia之间可能嵌套了其他元素:

<li>
  <article>
    <other>
      <a/>

如果嵌套是一致的,但articleli之间并不总是a元素,那么使用

//li/*/a[1]

这避免了//轴的计算成本比/贵。

最后,如果您知道您感兴趣的a元素始终是li元素的孙子元素,并且它们之间始终是article元素,请使用

//li/article/a[1]
  

当我将表达式更正为// li / article / a [1]'时,我得到第一个li的第一个`。

如果有多个//li/article/a[1]元素是a的子元素和article的孙元素,则

li会返回多个结果。如果这只返回一个结果

  • 您在只需要一个结果的上下文中调用此XPath表达式,例如如果您使用编程语言的XPath库或
  • 输入文档的结构更复杂

答案 1 :(得分:1)

我认为完成该操作的XPath将是.//ul/li/a[position()=1]

说明:

我将其全部拼写为.//ul/li/a的原因是,当您使用xpath时,如果存在错误,您的堆栈跟踪将准确显示定位器指向的内容,并且不那么模糊。但是,如果你不在乎,你显然可以简单地说:.//a

使用位置子句,您可以执行=1>1,或其他任何操作。我会选择使用[position()=1]而不是使用[1],因为Xpath不使用基于0的数组,这可能会使其他人看到您的定位器时感到困惑。我的意思是position=0,按逻辑,意味着空,对吧?

我用.开始我的定位器,因为就个人而言,有时我喜欢将我的定位器组合在一起。你真的不需要从dot char开始,但由于我在这种情况下使用//通配符,它​​实际上与没有点开始时相同,但具有链接的附加能力。

http://the-internet.herokuapp.com/

上测试了答案