XPath查询以获取元素的第n个实例


134

有一个HTML文件(我不控制其内容),该文件包含多个input元素,所有元素的固定id属性相同"search_query"。文件的内容可以更改,但是我知道我一直想获得input具有id属性的第二个元素"search_query"

我需要一个XPath表达式来执行此操作。我试过了,//input[@id="search_query"][2]但是不行。这是此查询失败的示例XML字符串:

<div>
  <form>
    <input id="search_query" />
   </form>
</div>

<div>
  <form>
    <input id="search_query" />
  </form>
</div>

<div>
  <form>
    <input id="search_query" />
  </form>
</div>

请记住,以上只是示例,其他HTML代码可能完全不同,并且这些input元素可以出现在没有一致文档结构的任何地方(但我保证始终至少会有两个input元素的id属性为"search_query")。

正确的XPath表达式是什么?


好问题,+ 1。请参阅我的答案以获取对该问题的完整说明以及所需的解决方案。
Dimitre Novatchev

7
关键点:给定ID的元素不得超过一个(因此问题中的HTML实际上是无效的)。在实践中,无论如何,浏览器都可以让您做到这一点,但是如果您这样做,您会错过使用ID的唯一好处,那就是它们表示“我是唯一的”(而类被设计用于非唯一符号)。
machineghost

Answers:


244

这是一个常见问题解答

//somexpression[$N]

意思是“查找所选择的每个节点//somexpression$N其父节点的第一个子节点”。

您想要的是

(//input[@id="search_query"])[2]

切记[]运算符的优先级(优先级)比//缩写的优先级高。


6
我喜欢这个答案。我没有考虑过优先级问题(我只是假设简单的从左到右的优先级)。
rlandster

10
@rlandster:“优先”一词可能令人困惑。的缩写形式//input[@id='search_query'][2]为:/descendat-or-self::node()/child::input[attribute::id='search_query'][position()=2]

21
对于那些从Google到这里的人-编号从1开始-[1]是第一个元素,依此类推
Jan Mares '18

奇怪的是,在这些XPath查询中,这类数组以1开头。
Ivotje50

@ Ivotje50是XPath序列和数组是基于1的
Dimitre Novatchev

21

这似乎可行:

/descendant::input[@id="search_query"][2]

我摘自Michael Kay撰写的“ XSLT 2.0和XPath 2.0程序员参考,第四版”。

XML路径语言规范http://www.w3.org/TR/xpath/#path-abbrev的“缩写语法”部分中也有一条注释,它提供了一条线索。


非常感谢您的回答。在我的情况下,接受的解决方案将无法正常工作,因为我在机器人框架中使用了xpath,该机器人将不接受以方括号开头的路径。但是,这应该可以解决问题
dahui
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.