XPATH: выбрать узлы с заданным именем, которые сразу же следуют за некоторыми конкретными узлами - PullRequest
14 голосов
/ 16 июня 2011

лучше всего показано на упрощенном примере:

<?xml version="1.0" encoding="utf-8"?>
<root>
    <A name="wrong"></A>
    <B>not this</B>
    <A name="right">
      <subA></subA>
    </A>
    <B>yes, this</B>  <!-- I want only this one -->
    <A name="right">
      <subA></subA>
    </A>
    <C>dont want this</C>
    <B>not this either</B>  <!-- not immediately following -->
</root>

Мне нужны все <B> узлы, которые сразу , следующие за <A> узлом с атрибутом name равны "right".

Что я пробовал:

//A[@name="right"]/following-sibling::*[1]

, который выбирает любой узел, следующий сразу за "правым" <A> (т.е. включая <C>). Я не вижу, как сделать это только <B>. Это не сработало:

//A[@name="right"]/following-sibling::*[1 and B]

Вот этот:

//A[@name="right"]/following-sibling::B[1]

выберет сначала <B> после "правильного" <A>, но не обязательно сразу после единица.

Ответы [ 3 ]

9 голосов
/ 16 июня 2011

Вы были почти там:

//A[@name='right']/following-sibling::*[position()=1 and self::B]

дает ровно один узел в вашем образце.

Для ссылки на элемент name в условии вам необходимо self.Просто [B] будет означать элемент с text , точно равным B.

2 голосов
/ 16 июня 2011

Просто чтобы указать, что вы не так далеко с первым XPath, показанным в вашем вопросе:

  //A[@name='right']/following-sibling::*[1][local-name()='B']

position() здесь не обязательно.

0 голосов
/ 16 июня 2011

Вы можете попробовать это //B[preceding-sibling::A[1][@name='right']] Это вернет вам интересующий вас узел.

Надеюсь, это поможет

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...