XPath: выберите первый элемент с определенным атрибутом

XPathbookstore/book[1] выбирает первый книжный узел подbookstore.

Как выбрать первый узел, который соответствует более сложному условию, например, первый узел, который соответствует/bookstore/book[@location='US']

Ответы на вопрос(8)

Самый простой способ найти первый английский узел книги (во всем документе), принимая во внимание более сложный структурированный XML-файл, например:

<bookstore>
 <category>
  <book location="US">A1</book>
  <book location="FIN">A2</book>
 </category>
 <category>
  <book location="FIN">B1</book>
  <book location="US">B2</book>
, </category>
</bookstore> 

такое выражение xpath:

/descendant::book[@location='US'][1]

С помощью онлайнтестер xpath Я пишу этот ответ ...
За это:

<table id="t2"><tbody>
<tr><td>123</td><td>other</td></tr>
<tr><td>foo</td><td>columns</td></tr>
<tr><td>bar</td><td>are</td></tr>
<tr><td>xyz</td><td>ignored</td></tr>
</tbody></table>

следующий xpath:

id("t2") / tbody / tr / td[1]

выходы:

123
foo
bar
xyz

поскольку1 значит выбрать всеtd элементы, которые являются первым потомком своего собственного прямого родителя.
Но следующий xpath:

(id("t2") / tbody / tr / td)[1]

выходы:

123

/bookstore/book[@location='US'][1] работает только с простой структурой.

Добавьте немного больше структуры и вещи ломаются.

С

<bookstore>
 <category>
  <book location="US">A1</book>
  <book location="FIN">A2</book>
 </category>
 <category>
  <book location="FIN">B1</book>
  <book location="US">B2</book>
 </category>
</bookstore> 

/bookstore/category/book[@location='US'][1] доходность

<book location="US">A1</book>
<book location="US">B2</book>

не "первый узел, который соответствует более сложному условию"./bookstore/category/book[@location='US'][2] ничего не возвращает

С помощью скобок вы можете получить результат, для которого был задан исходный вопрос:

(/bookstore/category/book[@location='US'])[1] дает

<book location="US">A1</book>

а также(/bookstore/category/book[@location='US'])[2] работает как положено.

 18 апр. 2012 г., 20:47
Автор принятого ответа здесь. Рассмотрен вопрос ОП/bookstore/book[1] и не(/bookstore/book)[1], Случай, который вы предоставили, отличается от того, о котором просил ОП. Предположительно, ОП принял мой ответ, так как он сделал то, что ожидал (и попросил).
 18 сент. 2012 г., 13:52
Я также нахожу этот ответ более правильным, чем выбранный, поскольку в моем случае у меня также была более сложная структура, в которой простое добавление [1] возвращало несколько узлов. Спасибо!
 11 мая 2012 г., 11:01
Этот ответ помог мне в этом особом случае. Может ли кто-нибудь объяснить, почему он не «обрабатывает» более сложные ситуации? Поскольку в основном он находит список из двух элементов, [2] должен просто забрать его (в моем мире)
 18 дек. 2012 г., 11:57
Скобки работают! Вы также можете добавить еще путь после (..) [1], например:'(//div[text() = "'+ name +'"])[1]/following-sibling::*/div/text()', В случае совпадения множества узловname.
 05 нояб. 2013 г., 22:03
Я меняю свое мнение. Через некоторое время я понял, о чем говорил этот ответ, и если бы я не увидел пример ФП, я бы за это проголосовал. Я полагаю, что я реагировал на тон этого ответа; если бы @tkurki объяснил немного больше об отделении условия от выбора первого узла, я бы сразу это увидел. Возможно, то же самое для JonFingland.

В качестве объяснения ответа Джонатана Фингланда:

multiple conditions in the same predicate ([position()=1 and @location='US']) must be true as a whole multiple conditions in consecutive predicates ([position()=1][@location='US']) must be true one after another this implies that [position()=1][@location='US'] != [@location='US'][position()=1]
while [position()=1 and @location='US'] == [@location='US' and position()=1] hint: a lone [position()=1] can be abbreviated to [1]

Вы можете создавать сложные выражения в предикатах с помощью логических операторов & quot;and& Quot; и & quot;or& quot; и с булевыми функциями XPathnot(), true() а такжеfalse(), Кроме того, вы можете заключить подвыражения в скобки.

Решение Вопроса

использование(/bookstore/book[@location='US'])[1]

Сначала будут получены элементы книги с атрибутом местоположения, равным «US». Затем он выберет первый узел из этого набора. Обратите внимание на использование скобок, которые требуются в некоторых реализациях.

(обратите внимание, это не то же самое, что/bookstore/book[1][@location='US'] unless the first element also happens to have that location attribute )

 05 апр. 2016 г., 08:27
@JonathanFingland, который вы неправильно поняли - прочитайте ответ Кевина Дриджера снова вместе с контекстом вопроса Александра В. Ильина. Вы оба имеете в виду одно и то же.
 17 апр. 2012 г., 21:39
Это получит все книги из «США». (/ bookstore / book [@ location = 'US & apos;]) [1] получит первый.
 11 мар. 2011 г., 20:04
Как я могу сделать то же самое для // bookstore / book [@ location = & apos; US & apos;]?
 18 апр. 2012 г., 20:38
@KevinDriedger/bookstore/book[@location='US'][1] не возвращает все книги из "США". Я проверял это много раз и на разных языках & apos; Реализации xpath./bookstore/book[@location='US'][1] возвращает первый «США» книга под книжным магазином. Если есть несколько книжных магазинов, то он вернет первый из каждого. Это то, о чем просил OP (первый узел в книжном магазине). Ваша версия возвращает только одну книгу из всех книжных магазинов (первый матч).
    <bookstore>
     <book location="US">A1</book>
     <category>
      <book location="US">B1</book>
      <book location="FIN">B2</book>
     </category>
     <section>
      <book location="FIN">C1</book>
      <book location="US">C2</book>
     </section>
    </bookstore> 

Так, учитывая вышеизложенное; Вы можете выбрать первую книгу с

(//book[@location='US'])[1]

И это найдет первое место, где есть США. [A1]

//book[@location='US']

Вернул бы узел, установленный со всеми книгами с местоположением US. [А1, В1, С2]

(//category/book[@location='US'])[1]

Вернет первое местоположение книги США, которое существует в категории в любом месте документа. [В1]

(/bookstore//book[@location='US'])[1]

вернет первую книгу с местоположением US, которое существует в любом месте под книжным магазином корневого элемента; делая часть книжного магазина избыточной. [A1]

В прямой ответ:

/bookstore/book[@location='US'][1]

Вернет вам первый узел для элемента книги с местоположением US, которое находится в книжном магазине [A1]

Между прочим, если вы хотите, в этом примере, чтобы найти первую книгу США, которая не была прямым потомком книжного магазина:

(/bookstore/*//book[@location='US'])[1]

Используйте индекс, чтобы получить нужный узел, если xpath сложный или более одного узла присутствует с одним и тем же xpath.

пример: (// книжный магазин [@location = 'US & apos;]) [index]

Вы можете дать номер, какой узел вы хотите.

например

<input b="demo">

А также

(input[@b='demo'])[1]
 17 мар. 2017 г., 13:14
Пожалуйста, укажите, почему ваш ответ должен работать.

Ваш ответ на вопрос