Нахождение индекса позиции комментария () - PullRequest
0 голосов
/ 20 сентября 2019

Столкнулся с этим:

<div>
some text
<!-- this is the hook comment-->
target part 1
target part 2
<!-- this is another comment-->
some other text
</div> 

Я пытаюсь получить желаемый результат:

цель часть 1 цель часть 2

Количество комментариев и текстовых элементов неизвестно, но целевой текст всегда идет после комментария, содержащего hook.Поэтому идея состоит в том, чтобы найти position() соответствующего comment() и получить следующий элемент.

Есть несколько предыдущих вопросов о поиске позиции элемента, содержащего определенный текст или по атрибуту , но comment() - странная утка, и я не могу изменить ответы в этой ситуации.Например, попытка вариации ответов:

//comment()[contains(string(),'hook')]/preceding::*

или использование preceding-sibling::* ничего не возвращает.

Поэтому я решил попробовать что-то еще.count(//node()) xml возвращает 6//node()[2] возвращает соответствующий comment().Но когда я пытаюсь получить позицию этого комментария, используя index-of() (который должен вернуть 2)

index-of(//node(),//comment()[contains(string(),'hook')])

, он возвращает 3!

Конечно, я могуне обращайте на это внимания и используйте индексную позицию 3 в качестве позиции для целевого текста (вместо увеличения 2 на 1), но мне было интересно, во-первых, почему результат такой, какой он есть, и, во-вторых, имеет ли он какой-либонепреднамеренные последствия.

1 Ответ

1 голос
/ 20 сентября 2019

Нет необходимости сначала находить position() элементов, если вы хотите получить узлы между двумя комментариями (FYI position() зависит от всего выбранного набора узлов).

Вы можете получитьэлементы непосредственно - здесь они text() узлов.Таким образом, файл примера, такой как

<?xml version="1.0" encoding="UTF-8"?>
<root>
    <div>
    some text
    <!-- this is the hook comment-->
    target part 1
    target part 2
    <!-- this is another comment-->
    some other text
        <!-- this is another comment-->
    no one needs this
        <!-- this is another comment-->
    this is also useless
        <!-- this is another hook comment-->
    second target text
        <!-- this is another comment-->
    again some useless crap
        <!-- this is another comment-->
    and the last piece that noone needs
    </div> 
</root>

, может быть запрошен со следующим выражением

//comment()[contains(string(),'hook')]/following-sibling::text()[preceding-sibling::comment()[1][contains(string(),'hook')]]

, что приведет к

target part 1
target part 2

second target text

Если вам нужен только первый блок,ограничьте выражение первым элементом:

(//comment()[contains(string(),'hook')]/following-sibling::text()[preceding-sibling::comment()[1][contains(string(),'hook')]])[1]

Его результат будет

target part 1
target part 2

по желанию.


Если вы можете использовать XPath-2.0, вы можете добавить /position() к вышеприведенным выражениям, чтобы получить положение comment() s.Но, как упоминалось выше, они относятся к узлам комментариев.Таким образом, результат будет 1 2.

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