В чем разница между использованием "../" и "parent" в запросе XPath? - PullRequest
4 голосов
/ 10 июня 2009

В чем разница между использованием "../" и "parent" для получения родительского узла в запросе XPath. Я думал, что они были синонимами.

Учитывая следующие два запроса XPath, есть ли разница между этими двумя?

//Node/id[@type='image']/id[@attr1='myVal']/../../*

//Node/id[@type='image']/id[@attr1='myVal']/parent::*/parent::*

Я работаю над приложением C # / ASP.net и, используя первый XPath-запрос, получаю фактически первого брата, предшествующего элементу Node. То, что я ищу, - это сам элемент Node и все его дочерние элементы. Второй запрос XPath даст мне ожидаемый результат.

Мне интересно, почему здесь есть разница.

Ответы [ 2 ]

5 голосов
/ 10 июня 2009

Вы не получаете тот же набор результатов, потому что * ваши выражения не эквивалентны друг другу. *

Рассмотрим:

1. Внук целевого узла

// Node / идентификатор [@ тип = 'Изображение'] / идентификатор [@ attr1 = 'myVal']

2. Дочерний элемент целевого узла (родитель внука) (эквивалентные выражения)

// Node / идентификатор [@ типа = 'Изображение'] / идентификатор [@ attr1 = 'myVal'] /..

// Node / идентификатор [@ тип = 'Изображение'] / идентификатор [@ attr1 = 'myVal'] / родитель :: *

3. Целевой узел (прародитель внука) (эквивалентные выражения)

// Node / идентификатор [@ типа = 'Изображение'] / идентификатор [@ attr1 = 'myVal'] /../..

// Узел / id [@ type = 'image'] / id [@ attr1 = 'myVal'] / parent :: * / parent :: * <- * * * ВАШ 2-Й EXPR * * *</p>

4. Все дочерние узлы целевого узла (эквивалентные выражения)

// Node / id [@ type = 'image'] / id [@ attr1 = 'myVal'] /../../* <- * * * YOUR 1-й EXPR * * *</p>

// Node / идентификатор [@ тип = 'Изображение'] / идентификатор [@ attr1 = 'myVal'] / родитель :: * / родитель :: * / *


Попробуйте эквивалент ваших выражений (например, «//parent/child[@id="2"]/grandchild[@id="2.1"]/../../* ') на испытательном стенде XPath, связанном ниже. Он выделяет красным, какие узлы соответствуют различным выражениям XPath, которые вы передаете ему.

http://www.whitebeam.org/library/guide/TechNotes/xpathtestbed.rhtm

5 голосов
/ 10 июня 2009

Быстрый ответ; да, ../ и parent :: * эквивалентны, но вы получите разные результаты, потому что ваши выражения XPath отличаются.

Более длинный ответ;

Выражения parent :: node () и .. эквивалентны, причем последний является сокращенной формой первого согласно Рекомендации W3C XPath .

Вы получите похожее поведение от parent :: *, потому что XML формирует дерево, поэтому любой дочерний элемент может иметь не более одного родителя.

Причина, по которой вы получите разные результаты, заключается в том, что это разные запросы. Первый имеет дополнительный * в конце (../../*), который, вероятно, возвращает последовательность дочерних элементов вашего узла.

Второй получает именно родительский элемент родительского узла контекста (в сокращенной форме ../ ..), который является вашим интересующим элементом Node.

Пример:

Для документа

<?xml version="1.0" encoding="UTF-8"?>
<root>
    <Node>
        <id type="image">
            <id attr1="myVal"> </id>
        </id>
    </Node>
</root>

Запросы

//Node/id[@type='image']/id[@attr1='myVal']/../../* 

и

//Node/id[@type='image']/id[@attr1='myVal']/parent::*/parent::*/* 

вернуть идентификатор узла [@ type = 'image']

В то время как запросы

//Node/id[@type='image']/id[@attr1='myVal']/../..

и

//Node/id[@type='image']/id[@attr1='myVal']/parent::*/parent::*

вернуть узел узла.

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