2011-01-07 23 views
21
documento XML

:Operador XPath "! =". ¿Como funciona?

<doc> 
    <A> 
     <Node>Hello!</Node> 
    </A> 

    <B>  
     <Node/> 
    </B> 

    <C> 
    </C> 

    <D/> 
</doc> 

¿Cómo evaluaría las siguientes consultas XPath?

/doc/A/Node != 'abcd' 
/doc/B/Node != 'abcd' 
/doc/C/Node != 'abcd' 
/doc/D/Node != 'abcd' 

yo esperaría TODO de éstos para evaluar a cierto.

Sin embargo, aquí están los resultados:

/doc/A/Node != 'abcd'  true 
/doc/B/Node != 'abcd'  true 
/doc/C/Node != 'abcd'  false 
/doc/D/Node != 'abcd'  false 

Es ésta comportamiento esperado? ¿O es un error con mi proveedor de XPath (jaxen)?

+0

Buena pregunta, +1. Consulte mi respuesta para obtener una explicación y una regla y una solución que "debe recordar".:) –

Respuesta

1

Desde el XPath spec:

Si un objeto a comparar es un conjunto de nodos y el otro es una cadena, entonces la comparación será verdadera si y sólo si hay un nodo en el node- set tal que el resultado de realizar la comparación en el valor de cadena del nodo y la otra cadena sea verdadero.

Esto significa que si el conjunto de nodos está vacío (como en los casos C y D), el resultado de la expresión booleana será falso, ya que no hay ningún nodo al que pueda aplicarse la desigualdad.

Para evitar este comportamiento y obtener el resultado deseado con una expresión como:

count(/doc/C/Node) = 0 or /doc/C/Node != 'abcd' 
+1

+1 Bueno para citar la especificación -1 Malo para la recomendación ... –

42

Recomendación: Nunca utilice el operador != para comparar la desigualdad, donde uno o ambos argumentos son conjuntos de nodos.

By definition la expresión:

$node-set != $value 

evalúa a true() exactamente cuando hay al menos un nodo en $node-set tal que su valor de cadena no es igual al valor de la cadena de $value.

Usando esta definición:

$empty-nodeset != $value 

siempre es false(), porque no hay ni un solo nodo en $empty-nodeset para lo cual mantiene la desigualdad.

Solución:

Uso:

not($node-set = $value) 

, entonces obtendrá todos los resultados true(), como quería.

+0

+1. Este consejo ya me ahorró muchos nervios. – Flack

+0

+1 Expresión correcta. –