xpath выбирает дочерние узлы, чьи родители не одного типа - PullRequest
0 голосов
/ 04 сентября 2018

Я прошу прощения за, вероятно, вводящее в заблуждение название, я не знал, как его сформулировать.

У меня есть огромный XML-файл с большим количеством элементов, и мне нужно получить определенный элемент (с именем w: r), но только если этот элемент не находится внутри другого элемента с именем w: r

например:

<w:r>
    test
</w:r>

следует выбрать один элемент

<w:r>
    <w:r>
        test
    </w:r>
</w:r>

также должен выбирать только ОДИН элемент (внешний), а не два.

Мое текущее решение: //*[local-name()='r'], но оно выбирает два элемента для второго примера (один - внешний элемент, а другой - внутренний элемент)

1 Ответ

0 голосов
/ 05 сентября 2018

Вы можете извлечь внешние элементы w:r с помощью следующего выражения XPath:

//*[local-name()='r' and not(parent::*[local-name()='r'])]

Для следующего XML (для целей тестирования):

<?xml version='1.0' encoding='utf-8'?>
<root xmlns:w="xxx">
    <w:r t="c">
        test
    </w:r>  
    <w:r t="d">
        <w:r t="h">
            test
        </w:r>
    </w:r>
    <w:r t="e">
        <a>
            <b>
                <c>...
                    <w:r t="i">Something</w:r>
                    ...
                </c>
            </b>
        </a>
    </w:r>
</root>

Вывод:

<w:r xmlns:w="xxx" t="c"/>  
<w:r xmlns:w="xxx" t="d"/>
<w:r xmlns:w="xxx" t="e"/>

Это означает, что все внешние элементы w:r выбираются выражением.


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

//*[local-name()='r' and not(ancestor::*[local-name()='r'])]

Для примера XML результат такой же, но семантика другая.

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