web-dev-qa-db-fra.com

Expression Xpath avec plusieurs prédicats

J'essaie de construire une expression complexe xpath qui répondra à la condition suivante.

À partir des données XML ci-dessous, renvoie le Utilisateur entité qui:

  1. Son identifiant est " user1 "
  2. Son nom est " Utilisateur 1 "
  3. Il a 2 profils différents qui sont " opérateur " et " admin " (je ne connais pas l'ordre exact à venir)

     

    <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>
    

Quelqu'un peut-il s'il vous plaît fournir un exemple pour un tel cas?

EDIT: Ajout d'une entité de profil complexe

45
user41767

Ce qui suit devrait faire ce que vous recherchez:

/root/user[login='user1' and 
           name='User 1' and 
           profile='admin' and
           profile='operator']

Avoir deux tests pour la valeur profile peut sembler étrange, mais comme il existe plusieurs nœuds profile, la condition sera satisfaite tant qu’au moins un nœud correspond au test. 

La raison pour laquelle vous pouvez comparer profile directement à un string, même s’il s’agit bien d’un node, c’est que le string-value d’un nœud d’élément est le string-value de tous ses descendants concaténés ensemble, qui dans ce cas est uniquement le contenu de value

Si profile contient plus d'éléments que value, vous devrez utiliser un test de prédicat légèrement plus complexe pour déterminer l'existence d'un nœud profile correspondant basé uniquement sur value (cela devrait fonctionner avec votre question mise à jour):

/root/user[login='user1' and 
           name='User 1' and 
           profile[value='admin'] and
           profile[value='operator']]
70
Greg Beech

Voici une réponse plus exacte (à l'heure actuelle, la réponse de Greg Beech ne vérifie pas la condition 3. dans le problème: l'élément user doit avoir exactement 2 profile enfants):

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

En supposant que users est la racine: 

/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