Выражение Xpath с несколькими предикатами
Вопрос
Я пытаюсь создать сложное выражение xpath, которое будет отвечать следующему условию.
Из приведенных ниже XML-данных возвращает Пользователь сущность , которая:
- Его логин - это "пользователь1"
- Его зовут "Пользователь 1"
У него есть 2 разных значения профиля, которые являются "оператор" и "администратор" (Я не знаю точного порядка действий)
<user> <login>user1</login> <name>User 1</name> <profile> <value>admin</value> <id>2</id> <description>admin users</description> </profile> <profile> <value>operator</value> <id>1</id> <description>Operator</description> </profile> </user> <user> <login>user2</login> <name>User 2</name> <profile> <value>admin</value> <id>4</id> <description>admins users</description> </profile> <profile> <value>poweruser</value> <id>5</id> <description>power users</description> </profile> </user> </root>
Может кто-нибудь, пожалуйста, привести пример для такого случая?
Редактировать:Добавлен сложный объект профиля
Решение
Следующее должно делать то, что вам нужно:
/root/user[login='user1' and
name='User 1' and
profile='admin' and
profile='operator']
Имея два теста для profile
значение может показаться странным, но поскольку существует несколько profile
узлы, то условие будет выполняться до тех пор, пока хотя бы один узел соответствует тесту.
Причина, по которой вы можете сравнить profile
непосредственно к string
, даже несмотря на то , что на самом деле это node
это тот самый string-value
узла элемента - это string-value
из всех его потомков, объединенных вместе, что в данном случае является просто содержимым value
.
Если profile
содержал больше элементов, чем value
вам пришлось бы использовать немного более сложный тест на предикат, чтобы определить наличие совпадения profile
узел, основанный только на value
(это должно сработать с вашим обновленным вопросом):
/root/user[login='user1' and
name='User 1' and
profile[value='admin'] and
profile[value='operator']]
Другие советы
Вот более точный ответ (в настоящее время ответ Грега Бука не проверяет условие 3.в проблеме:в user
элемент должен иметь ровно 2 profile
дети):
/*/user
[login='user1'
and
name='User 1'
and
not(profile[3])
and
profile/value='admin'
and
profile/value='operator'
]
Предполагая users
является корнем:
/users/user[login='user1' and name='User 1'
and (profile='admin' and profile='operator')]
/root/user[login='user1' and name='User 1' and profile/value='admin' and profile/value='operator'