Document XML:
<doc>
<A>
<Node>Hello!</Node>
</A>
<B>
<Node/>
</B>
<C>
</C>
<D/>
</doc>
Comment évalueriez-vous les requêtes XPath suivantes?
/doc/A/Node != 'abcd'
/doc/B/Node != 'abcd'
/doc/C/Node != 'abcd'
/doc/D/Node != 'abcd'
Je m'attendrais à [~ # ~] tous [~ # ~] à évaluer à vrai.
Voici cependant les résultats:
/doc/A/Node != 'abcd' true
/doc/B/Node != 'abcd' true
/doc/C/Node != 'abcd' false
/doc/D/Node != 'abcd' false
Est-ce un comportement attendu? Ou est-ce un bug avec mon fournisseur XPath (jaxen)?
Recommandation : n'utilisez jamais l'opérateur !=
Pour comparer l'inégalité lorsqu'un ou les deux arguments sont des ensembles de nœuds.
Par définition l'expression :
$node-set != $value
correspond à true()
exactement quand il y a au moins un nœud dans $node-set
de sorte que sa valeur de chaîne n'est pas égale à la valeur de chaîne de $value
.
En utilisant cette définition :
$empty-nodeset != $value
est toujours false()
, car il n'y a même pas un seul nœud dans $empty-nodeset
pour lequel l'inégalité se maintient.
Solution :
Utilisez :
not($node-set = $value)
Ensuite, vous obtenez tous les résultats true()
, comme souhaité .
De la XPath spec :
Si un objet à comparer est un ensemble de nœuds et l'autre une chaîne, alors la comparaison sera vraie si et seulement s'il y a un nœud dans l'ensemble de nœuds de telle sorte que le résultat de la comparaison sur la valeur de chaîne du nœud et l'autre chaîne est vraie.
Cela signifie que si l'ensemble de nœuds est vide (comme dans vos cas C et D), le résultat de l'expression booléenne sera faux, car il n'y a pas de nœud auquel l'inégalité peut s'appliquer.
Vous pouvez contourner ce problème et obtenir le résultat souhaité en utilisant une expression comme:
count(/doc/C/Node) = 0 or /doc/C/Node != 'abcd'