Запрос XPath для получения n-го экземпляра элемента

Существует 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

Это FAQ:

//somexpression[$N]

означает "Найти каждый node, выбранный //somexpression, который является $N -й дочерью его родителя".

Вы хотите:

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

Помните. Оператор [] имеет более высокий приоритет (приоритет), чем аббревиатура //.

Ответ 2

Это работает:

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

Я перехожу к нему из "XSLT 2.0 и XPath 2.0 Programmer Reference, 4th Edition" Майкла Кей.

Также есть примечание в разделе "Сокращенный синтаксис" спецификации языка XML Path http://www.w3.org/TR/xpath/#path-abbrev, который дал ключ.