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