Захват узлов, которые не являются потомками других узлов, исключая текущий контекст

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

<root>
    <my_element>
        <my_element>
            Some Text
        </my_element>
    </my_element>
</root>

Я знаю, что уже могу делать то, что хочу, используя этот xpath:

Context: /
xPath: descendant::my_element[not(ancestor::my_element)]

Что вернет этот набор результатов:

<root>
    [<my_element>]
        <my_element>
            Some Text
        </my_element>
    [</my_element>]
</root>

Это ожидаемое поведение того, что я хочу. Но я хочу иметь возможность изменить контекст на:

/my_element

И получите этот набор результатов:

<root>
    <my_element>
        [<my_element>]
            Some Text
        [</my_element>]
    </my_element>
</root>

Я изо всех сил старался просматривать документы xPath и ничего не придумал. Возможно, кто-то здесь может дать некоторое представление?

Спасибо!

  • изменить - я хочу иметь возможность выбрать потомка my_element, который не является предком my_element, за исключением узла контекста.

  • отредактируйте снова - для дальнейшего объяснения.

Я хочу иметь запрос xpath, который выбирает узлы my_element, если узел не является дочерним элементом my_element. Но если контекст xpath установлен на узел my_element, то я не хочу, чтобы этот узел учитывался в выражении. Таким образом, xpath будет соответствовать следующему узлу my_element, хотя на самом деле он является дочерним элементом my_element.

  • редактируй еще раз -

Вот еще несколько примеров.

<root>
    <a>
        <a>
            <b>
                <a>
                    Hello!
                </a>
            </b>
            <a>
                <b>
                    Hello Again
                    <a>
                        Sub
                    </a>
                </b>
            </a>
        </a>
    </a>
</root>

Context: /root/
Desire: Want to grab all A nodes, so long as they aren't a descendant of A

Result:
<root> == Context
    [<a>]
        <a>
            <b>
                <a>
                    Hello!
                </a>
            </b>
            <a>
                <b>
                    Hello Again
                    <a>
                        Sub
                    </a>
                </b>
            </a>
        </a>
    [</a>]
</root>

Context: /root/a/
Desire: Want to grab all A nodes, so long as they aren't a descendant of A, not including the context /root/a/

Result:
<root>
    <a> == Context
        [<a>]
            <b>
                <a>
                    Hello!
                </a>
            </b>
            <a>
                <b>
                    Hello Again
                    <a>
                        Sub
                    </a>
                </b>
            </a>
        [</a>]
    </a>
</root>

Context: /root/a/a/
Desire: Want to grab all A nodes, so long as they aren't a descendant of A, not including the context /root/a/a/

Result:
<root>
    <a>
        <a> == Context
            <b>
                [<a>]
                    Hello!
                [</a>]
            </b>
            [<a>]
                <b>
                    Hello Again
                    <a>
                        Sub
                    </a>
                </b>
            [</a>]
        </a>
    </a>
</root>

Context: /root/a/a/a/
Desire: Want to grab all A nodes, so long as they aren't a descendant of A, not including the context /root/a/a/a/

Result:
<root>
    <a>
        <a>
            <b>
                <a>
                    Hello!
                </a>
            </b>
            <a> == Context
                <b>
                    Hello Again
                    [<a>]
                        Sub
                    [</a>]
                </b>
            </a>
        </a>
    </a>
</root>

Я надеюсь, что это сделает мои желания более ясными. Спасибо всем, кто старается!


person Kyle    schedule 10.04.2011    source источник
comment
@Kyle: Разве это не my_element дети? Если вам не нужен потомок my_element, у которого нет предка my_element, за исключением узла контекста и его предка.   -  person    schedule 11.04.2011
comment
Ваш последний прав. Я хочу иметь возможность выбрать потомка my_element, который не является предком my_element, за исключением узла контекста.   -  person Kyle    schedule 11.04.2011
comment
@Kyle: я думаю, что вы не можете в XPath 1.0, потому что вам нужно ссылаться на узел контекста.   -  person    schedule 11.04.2011
comment
@Alejandro: Было бы возможно, если бы я поместил контекст внутри xpath и проверил его там? IE: /мой_элемент/потомок::мой_элемент[не(предок::мой_элемент)]   -  person Kyle    schedule 11.04.2011
comment
@Kyle: Нет. Единственное выражение, которое я мог придумать, это ./descendant::my_element[1], которое выбирает первого потомка (тогда у него не будет предка my_element), но оно не будет выбирать остальную часть my_element в другой дочерней ветке узла контекста.   -  person    schedule 11.04.2011
comment
@Алехандро: Да. Но спасибо, что заглянули.   -  person Kyle    schedule 11.04.2011
comment
Хороший вопрос, +1. См. мой ответ для полного, короткого и простого однострочного решения XPath. :)   -  person Dimitre Novatchev    schedule 11.04.2011


Ответы (2)


Использование:

//my_element[not(.//my_element)]

При этом выбираются все элементы с именем my_element, у которых нет потомков my_element.

person Dimitre Novatchev    schedule 11.04.2011
comment
Это не выбирает самые внешние my_element с root в качестве узла контекста. - person ; 12.04.2011
comment
@Alejandro: Извините, не могли бы вы объяснить? OP хочет: я хочу иметь возможность выбрать потомка my_element, который не является предком my_element, за исключением узла контекста, и это то, что выбирает выражение XPath в моем ответе. ??? - person Dimitre Novatchev; 12.04.2011
comment
Не совсем. Видите, это сработает, за исключением того, что я хочу исключить контекстный узел из теста, который мог бы быть с помощью my_element. На самом деле, читая это снова, ты совершенно не согласен с тем, что я хотел. Без проблем. см. этот xpath: потомок:: мой_элемент [не (предок:: мой_элемент)]. Это прекрасно работает. За исключением случаев, когда для контекста xpath задано значение my_element, и в этом случае я не хочу, чтобы выражение xpath заботилось о родительском элементе (контекстном узле). Так что что-то вроде этого сработало бы, если бы это был действительный xpath: потомок::мой_элемент[не(предок::мой_элемент) кроме контекста] - person Kyle; 12.04.2011
comment
@ Кайл: я готов помочь. Здесь основная проблема в том, что вы до сих пор не объяснили проблему так, чтобы люди ее поняли (я определенно не понимаю - что значит dislude?). Пожалуйста, отредактируйте свой вопрос и объясните хорошо. @ Алехандро, если ты понял вопрос, пожалуйста, отредактируй его, чтобы больше людей, включая меня, могли его понять. Кажется, у доктора Кея те же трудности. - person Dimitre Novatchev; 12.04.2011
comment
@ Кайл: подсказка. Приведите простой пример. Не используйте такие имена, как my_element — они сбивают с толку. Используйте A, B, C. В примере определите, какой из них является начальным узлом контекста. Затем перечислите узлы, которые необходимо выбрать. Наконец, объясните, каким требованиям должен соответствовать выбор. - person Dimitre Novatchev; 12.04.2011

Я думаю, вы можете попасть в общую ловушку. Выражение XPath /root/my_element для ваших данных выберет только один элемент — самый внешний узел my_element. Но этот узел по-прежнему привязан к своим родителям, братьям, сестрам и детям. Когда вы отображаете результат выбора, узел часто будет отображаться вместе со своими дочерними элементами (на самом деле, всеми потомками) — не потому, что XPath выбрал дочерние элементы, а потому, что это удобный способ отобразить единственный выбранный узел.

С другой стороны, я еще раз прочитал вопрос и могу ошибаться - я догадался об этом из своеобразной записи, которую вы использовали для отображения результатов вашего выражения XPath.

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

person Michael Kay    schedule 11.04.2011
comment
OP запрашивает эквивалентное выражение XPath 1.0 для этого выражения XPath 2.0 .//my_element except .//my_element//my_element - person ; 12.04.2011