Проблема предиката XPath

У меня есть выражение XPath с предикатом, который выбирает имя и идентификатор человека из вложенного элемента, используя метод XPathNavigator.Select.

Это работает:

root/all_clients/client/client_name_and_ID[client_ID = 'xxx']

Это также работает:

root/all_clients/client[client_name_and_ID/client_ID = 'xxx']/client_name_and_ID

Когда я перевожу предикат на следующий уровень, он не работает:

root/all_clients[client/client_name_and_ID/client_ID = 'xxx']/client/client_name_and_ID

У меня получается не какая-то фильтрация, а весь набор.

Это связано с ограничением, присущим XPath, ASP.NET, или я делаю что-то глупое?

Далее следует фрагмент из соответствующего XML-файла:

<?xml version="1.0" encoding="utf-8"?>

<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:noNamespaceSchemaLocation="file:///n:\Projects\XML\Medical\Example_01.xsd">

<all_clients>

    <client>
        <client_name_and_ID>
            <first_name>Fred</first_name>
            <middle_name>James</middle_name>
            <last_name>Bowman</last_name>
            <client_ID>1</client_ID>
        </client_name_and_ID>
    </client>

    <client>
        <client_name_and_ID>
            <first_name>Mark</first_name>
            <middle_name>David</middle_name>
            <last_name>Colder</last_name>
            <client_ID>2</client_ID>
        </client_name_and_ID>
    </client>

    <client>
        <client_name_and_ID>
            <first_name>Joe</first_name>
            <last_name>Lewis</last_name>
            <client_ID>3</client_ID>
        </client_name_and_ID>
    </client>

    <client>
        <client_name_and_ID>
            <first_name>Sam</first_name>
            <last_name>Plank</last_name>
            <client_ID>4</client_ID>
        </client_name_and_ID>
    </client>
</all_clients>

</root>

person user304607    schedule 11.02.2011    source источник


Ответы (2)


Последний запрос соответствует элементу all_clients, который содержит любой соответствующий клиент под ним. Затем он выбирает клиентов под этим all_clients без применения фильтра, поэтому он выбирает все элементы клиента.

Вы должны сохранить фильтр для конца XPath. Сначала выберите нужный тип элемента, а затем примените фильтр к этим элементам. Попробуйте эти XPath:

<!-- Select client_ID element. -->
root/all_clients/client/client_name_and_ID/client_ID[. = 'xxx']

<!-- Select client_name_and_ID element. -->
root/all_clients/client/client_name_and_ID[client_ID = 'xxx']

<!-- Select client element. -->
root/all_clients/client[client_name_and_ID/client_ID = 'xxx']
person John Kugelman    schedule 11.02.2011
comment
Я вижу сейчас. Спасибо, Джон, за ответ и примеры. - person user304607; 11.02.2011

Это нормально. Все узлы client являются потомками узла all_clients. Поэтому он всегда будет соответствовать условию «все элементы с именем all_clients, имеющие хотя бы одно совпадение с потомком client/client_name_and_ID/client_ID = 'xxx'», что вы и закодировали.

person Alain Pannetier    schedule 11.02.2011
comment
Спасибо, Ален. Думаю, теперь я понял, особенно после прочтения примеров, опубликованных Джоном. - person user304607; 11.02.2011