为什么XPath last()函数不能正常工作?

Lov*_*one 4 java xml selenium xpath selenium-webdriver

我正在使用Java和Selenium编写测试.我需要将最后一个元素放在另一个元素中,所以我使用了last()函数,但问题是它在我应用时并不总是带给我最后一个元素:

//a//b[last()]
Run Code Online (Sandbox Code Playgroud)

 <a> 
   <l>
     <b>asas</b> 
   </l>
   <b>as</b>
 </a> 
Run Code Online (Sandbox Code Playgroud)

得到<b>as</b>它,它带给我:

<b>asas</b>

<b>as</b>
Run Code Online (Sandbox Code Playgroud)

但当我申请时:

 <a>      
   <b>asas</b> 
   <b>as</b>
 </a>
Run Code Online (Sandbox Code Playgroud)

它带给我:

<b>as</b>
Run Code Online (Sandbox Code Playgroud)

kjh*_*hes 10

这是XPath混淆的常见原因. 首先是直截了当的部分:

  • //a选择a文档中的所有元素.
  • //a//b选择b文档中作为a元素后代的所有元素.

到目前为止正常的东西 接下来是棘手的部分:

  1. 要选择兄弟姐妹中的最后一个b元素(在元素下面):a

    //a//b[last()]
    
    Run Code Online (Sandbox Code Playgroud)

    这里,过滤是b选择标准的一部分,因为[]它具有更高的优先级//.

  2. 要选择文档中的最后一个b元素(在元素下面):a

    (//a//b)[last()]
    
    Run Code Online (Sandbox Code Playgroud)

    这里last()是所有选定b元素列表的索引,因为()它用于覆盖默认优先级.

  • 是的,但是`//a//b[last()]`和`(//a//b)[last()]`不选择相同的。答案更新了扩展的解释。 (2认同)

Mic*_*Kay 5

我认为如果您记住“//”是“/descendant-or-self::node()/”的缩写,并且步骤“b”是“child::”的缩写,那么最容易理解该行为。 b”。所以

//b[last()]
Run Code Online (Sandbox Code Playgroud)

是一个缩写

/descendant-or-self::node()/child::b[position()=last()]
Run Code Online (Sandbox Code Playgroud)

这意味着“选择文档中的每个节点(属性和命名空间除外)。对于每个节点,形成名为“b”的子元素列表,并选择该列表中的最后一个元素”。

您询问信息来源。@kjhughes 建议阅读 XPath 1.0 推荐,事实上,它比许多规范更具可读性。但有时可能有点简洁;有时感觉就像解决填字游戏。我的“XSLT 2.0 程序员参考”(其中还包括大量有关 XPath 的材料)是为那些想要深入了解该语言如何工作的人编写的,但用更简单的英语进行了解释。这个特定主题位于第 627 页,如果您想了解其内容,很容易在网络上找到盗版副本。但我建议购买正版,因为滚动浏览 1300 页的扫描 PDF 并不是什么有趣的事情。