Подтвердить что ты не робот

Оператор XPath "! =". Как это работает?

XML-документ:

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

    <B>     
        <Node/>
    </B>  

    <C>
    </C>

    <D/>
</doc>

Как вы оцениваете следующие запросы XPath?

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

Я ожидал бы, что ВСЕ из них будут оцениваться до истины.

Однако, вот результаты:

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

Является ли это ожидаемым поведением? Или это ошибка с моим поставщиком XPath (jaxen)?

4b9b3361

Ответ 1

Рекомендация. Никогда не используйте оператор != для сравнения неравенства, где один или оба аргумента node -sets.

По определению выражение:

$node-set != $value

оценивается как true() точно, когда в $node-set имеется хотя бы один node, так что его строковое значение не равно строковому значению $value.

Используя это определение:

$empty-nodeset != $value 

всегда false(), потому что в $empty-nodeset не существует ни одного node, для которого выполняется неравенство.

Решение

Использование

not($node-set = $value)

Затем вы получаете все результаты true(), если хотите.

Ответ 2

Из Спецификация XPath:

Если один объект, который нужно сравнить, это node -set, а другой - строка, тогда сравнение будет истинным тогда и только тогда, когда есть node в node -set, так что результат выполнения сравнения по строковому значению node, а другая строка - true.

Это означает, что если node -set пуст (как в ваших случаях C и D), результат булевого выражения будет ложным, так как не существует node, к которому может применяться неравенство.

Вы можете обойти это поведение и получить желаемый результат с помощью выражения типа:

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