Подтвердить что ты не робот

Выражение 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: добавлен объект сложного профиля

4b9b3361

Ответ 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'