it-roy-ru.com

Выражение Xpath с несколькими предикатами

Я пытаюсь построить сложное выражение xpath, которое будет отвечать следующему условию.

Из приведенных ниже данных XML возвращает объект Пользователь , который:

  1. Его логин " user1 "
  2. Его зовут " Пользователь 1 "
  3. У него есть 2 разных значения профиля: " operator " и " 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>
    

Может кто-нибудь привести пример для такого случая?

Правка: Добавлен объект сложного профиля

45
user41767

Следующее должно делать то, что вы после:

/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']]
70
Greg Beech

Вот более точный ответ (в настоящее время ответ Грега Бича не проверяет условие 3. в задаче: элемент user должен иметь ровно 2 profile дочерних элемента):

/*/user
        [login='user1' 
        and            
         name='User 1' 
        and  
         not(profile[3])
        and          
         profile/value='admin' 
        and           
         profile/value='operator'
         ]
6
Dimitre Novatchev

Предполагая, что users является корнем: 

/users/user[login='user1' and name='User 1' 
            and (profile='admin' and profile='operator')]
1
dirkgently
/root/user[login='user1' and name='User 1' and profile/value='admin' and profile/value='operator'
0
Ankush Jetly