Вопрос

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

Из приведенных ниже XML-данных возвращает Пользователь сущность , которая:

  1. Его логин - это "пользователь1"
  2. Его зовут "Пользователь 1"
  3. У него есть 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'
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top