2009-02-20 14 views
39

Estoy intentando construir una expresión compleja de xpath que responderá a la siguiente condición.Expresión de Xpath con múltiples predicados

A partir de los datos XML a continuación, devuelve el entidad usuario que:

  1. Su LoginName es "usuario1"
  2. Su nombre es "Usuario 1"
  3. Él tiene 2 valores de perfiles diferentes que son "operador" y "admin" (no sé el exa Para ct adelante)

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

Por favor alguien puede suministrar un ejemplo para un caso así?

EDIT: Se ha añadido una entidad perfil complejo

Respuesta

64

Lo que sigue debe hacer lo que está buscando:

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

Tener dos pruebas para el valor profile puede parecer extraño, pero como hay múltiples nodos profile, entonces el co ndition se cumplirá siempre que al menos un nodo coincida con la prueba.

La razón puede comparar profile directamente a un string, a pesar de que en realidad es un node es que el string-value de un nodo elemento es el string-value de todos sus descendientes concatenados entre sí, que en este caso es sólo el contenido de value .

Si profile contenían más elementos que value que tendría que utilizar una prueba predicado un poco más complejo para determinar la existencia de un nodo a juego profile basada sólo en el value (esto debería funcionar con su pregunta actualizada):

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

Gracias por su rápida solución. Puedo usar una XPATH como esta, o puede cambiar la lógica: /root/user [login = 'user1'] [name = 'User 1'] [profile [value = 'admin']] [profile [ value = 'operator']] – user41767

+2

Interesante - No sabía que podría tener múltiples bloques de predicados, pero sí, parece que eso también funciona. Genial, ahora también he aprendido algo :-) –

+0

Múltiples predicados solo funcionan como AND, por supuesto, la sintaxis expandida te da O también, pero prefiero los múltiplos para mayor claridad. También podría hacer esto con hachas como anterior-hermano, pero eso sería un poco obtuso para un caso simple como este. – annakata

1

Suponiendo users es la raíz:

/users/user[login='user1' and name='User 1' 
      and (profile='admin' and profile='operator')] 
+0

Creo que te refieres a "iniciar sesión", etc. (no "@login", etc.). Estos son elementos, no atributos en el XML original. ;-) – Tomalak

+0

No sé lo que estaba pensando: P – dirkgently

6

Aquí es una respuesta más exacta (en la actualidad la respuesta de Greg Haya no comprueba la condición 3. en el problema: el elemento user deben tener exactamente 2 profile niños):

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

Gracias por mostrar la posibilidad de verificar el número exacto de elementos. Dicho esto, todavía no leo la condición 3 porque "debe tener exactamente 2 y (no 3 o más)". –

+0

@AloisMahdal, la pregunta establece: "3.Tiene 2 valores de perfiles diferentes que son" operador "y" admin "". La expresión XPath en esta respuesta comprueba exactamente esto: tiene los perfiles de 'admin' y 'operator' y no tiene un tercer perfil. Si hubiera un tercer valor de perfil, el usuario realmente tendría 3 valores de perfil diferentes, no 2. –

+1

Una descripción del trabajo dice que necesito hablar francés y alemán. Si hablo francés, alemán e italiano, ¿califico? Esto es sobre el inglés: no soy un hablante nativo y no un lingüista, así que podría estar equivocado, pero de la forma en que lo leí, supongo que a menos que se diga explícitamente (digamos, si realmente lo necesitan no deben hablar en italiano), tales las listas nunca son exclusivas (Tenga en cuenta que no estoy destinado a demostrar que está equivocado, solo estaba señalando una "zona gris" en el idioma. Lo siento por semi-OT) –

0
/root/user[login='user1' and name='User 1' and profile/value='admin' and profile/value='operator' 
Cuestiones relacionadas