Подтвердить что ты не робот

Xpath: получить узлы, у которых нет предка X

Я хочу, чтобы все узлы XML-документа не были потомками узлов X.

(Моя фактическая проблема немного сложнее, но я сейчас застрял с частью "не потомки" ).

4b9b3361

Ответ 1

Если вы переводите "не потомки", чтобы "не иметь предка", вы получаете выражение //*[not(ancestor::X)]. Это вернет все узлы в документе, которые не являются потомками узлов с именем "X".

Ответ 2

jarnbjo указывает на интуитивный способ сделать это, чтобы использовать //*[not(ancestor::X)]. У этого есть очень большая заслуга в том, что он будет работать независимо от того, как структурирован ваш документ, и что вы должны использовать в большинстве случаев.

Но если у вас очень большой документ, это может быть крайне неэффективно. Это очень дорогой вопрос. Он сообщает процессору XPath, чтобы он посетил каждый node в документе и проверил его предка node на наличие элемента с именем X. Хотя возможно, что процессор XPath достаточно умен, чтобы знать, что ему не нужно посещать потомки X для оценки этого запроса, это вряд ли.

Если у вас есть информация о том, где находится элемент X, и вы осторожны, вы можете написать более эффективный запрос. Например, если X является дочерним элементом элемента верхнего уровня, и у него много потомков, это будет намного быстрее:

/* | /*/* | /*/*[not(name()='X')]//*

Это находит элемент верхнего уровня, всех его непосредственных детей и потомков любого из его непосредственных детей, не названных X. Он не будет изучать ни одного из потомков X.

Аналогично, если вы знаете, что X близко к нижней части дерева, этот запрос может быть более эффективным:

//*[not(ancestor::*[position() <= 3][X])]

потому что он не будет проверять всю ось предка для каждого node, который он тестирует, только его последние три элемента. (Если процессор XPath не является достаточно глупым, чтобы исследовать каждый node на оси, когда он выполняет тесты, которые используют position(), каким он может быть.)

Как я уже сказал, большую часть времени самая простая версия будет лучшей, и большую часть времени она будет использоваться мной.