xpath中// node和/ descendant :: node之间有什么区别?

时间:2009-10-08 13:22:03

标签: xpath

在使用Selenium在网页中定位元素时,我使用了大量的XPath,并且最近使用node1 // node2转向使用node1 / descendant :: node2。这两种方法有什么区别?一个比另一个更有效吗?

用于演示的示例XML代码段:

<div id="books">
  <table>
    <tr><td class="title">Lord of the Rings</td><td class="author">JRR Tolkein</td></tr>
    <tr><td class="title">The Hitch-Hikers Guide to the Galaxy</td><td class="author">Douglas Adams</td></tr>
  </table>
</div>

所以它是:

id('books')//td[@class='title']

或:

id('books')/descendant::td[@class='title']

5 个答案:

答案 0 :(得分:34)

请参阅http://www.w3.org/TR/xpath#path-abbrev

//只是descendant :: axis

的缩写

修改

引用:

  

// para是/ descendant-or-self :: node()/ child :: para

的缩写

也就是说,它指的是所有para,它们是上下文节点的子节点或来自上下文节点的任何节点。据我所知,它转换为上下文节点的任何后代段。

答案 1 :(得分:11)

上下文组有所不同。 //para[1]是简称 /descendant-or-self::node()/child::para[1],返回其父项的第一个子项的每个段。 /descendant::para[1]仅返回整个子树中的第一个段落。

答案 2 :(得分:4)

在你的情况下

 id('books')//td[@class='title']

 id('books')/descendant::td[@class='title']

返回相同的结果。

但实际上,就像之前已经说过的那样,id('books')//td[@class='title']表示id('books')/descendant-or-self::node()/td[@class='title']在概念上与id('books')/descendant::td[@class='title']不同。

请参阅以下注释:

  

注意:位置路径// para [1]与位置路径/ descendant :: para [1]的含义不同。后者选择第一个后代para元素;前者选择所有后代的para元素,这些元素是他们父母的第一个孩子。

本说明取自http://www.w3.org/TR/xpath#path-abbrev

答案 3 :(得分:2)

除了简洁之外,我不知道有什么不同。

答案 4 :(得分:1)

我意识到这个答案更多的是功能上的正确性,但如果它对任何人有帮助,我今天偶然发现了一个关键区别。

根据后代的某些属性(如属性)选择元素时。例如:

...
<foo id="ID1">
    <bar>
        <baz at2="c" />
    </bar>
</foo>
<foo2 id="ID2">
    <bar>
        <baz at2="d" />
    </bar>
</foo2>
...

要选择具有属性 id 的后代的所有元素的 at2=c 属性:

这个 xpath 将选择 foo 和 foo2:

//*[//*[@at2="c"]]/@id

虽然这个 xpath 只会选择 foo:

//*[descendant::*[@at2="c"]]/@id