web-dev-qa-db-ja.com

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'  

私は、これらの[〜#〜] all [〜#〜]trueと評価されることを期待しています。

ただし、結果は次のとおりです。

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

これは予想される動作ですか?または、XPathプロバイダー(jaxen)のバグですか?

30
Keith

推奨事項:_!=_演算子を使用して、一方または両方の引数がノードセットである場合の不等式を比較しないでください。

定義により

_$node-set != $value
_

ストリング値が_$node-set_のストリング値と等しくないように、_$value_に少なくとも1つのノードがある場合、正確にtrue()に評価されます。

この定義を使用して

_$empty-nodeset != $value 
_

不等式が成立する_$empty-nodeset_には単一のノードすら存在しないため、常にfalse()です。

ソリューション

使用

_not($node-set = $value)
_

その後、必要に応じてすべての結果true()を取得します

57

XPath仕様 から:

比較する1つのオブジェクトがノードセットで、もう1つが文字列である場合、文字列値で比較を実行した結果がノードセットにノードがある場合にのみ、比較はtrueになります。ノードと他の文字列のtrueです。

つまり、ノードセットが空の場合(CやDの場合のように)、不等式を適用できるノードがないため、ブール式の結果はfalseになります。

次のような式を使用して、この動作を回避し、必要な結果を取得できます。

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