ここで挙げられている問題について、分かりやすく説明する為に更に条件を絞り込んでみました。fooは空のノード集合です。
self::* != foo
foo != foo
3 != foo
'あ' != foo
以上、全部偽でした。つまり空のノード集合は、ブール値以外の何と比較しても必ず偽でした。
true() != foo
MSXMLでは、このようにブール値と比較したときには、予想通りの結果が得られます。真です。4Suiteライブラリを使用すると偽でした。
ここで私は、3 != foo
(偽)にスポットを当ててみました。数値(3)とノード集合foo
を !=
で比較するとき、そのノード集合foo
に含まれるの各ノードにnumber
関数を適用して、3
に等しくないものが一つでもあれば真になります。number(foo)
と比較されるのではないのです(number(foo)
なら非数値(NaN)なので、3 != number(foo)
は真になりますし)。そしてこのノード集合foo
は空ですから、中にノードなんてありません。等しくないものが見つからないわけです。なんだかややこし過ぎて笑ってしまいました。
'あ' != foo
も全く同じです。foo
というノード集合に含まれるノードの中に、'あ'
でない文字列が見つからないので、偽なのです。
self::* != foo
にしても同様ですが少し複雑です。self::*
内の各ノードの文字列値それぞれと、foo
内の各ノードの文字列値それぞれとを比較して、一つでも異なるならばこれは真です。しかし、そもそもfoo
内にノードが無いので異なるものを見つけることが出来ず、よって偽になります。
しかし、するとtrue() != foo
は何故MSXMLで真になるのでしょうか。片方がブール値の場合は、各ノードではなくてノード集合自身にboolean関数が適用される
foo
内の各ノードにboolean
関数を適用した結果、その中に、一つでもfalse()
がなければtrue() != foo
は真にならないはずです。実装の不具合でしょうか。
更に、foo = foo
やfoo != foo
では何が行われているのか私にはさっぱりわかりません。
私は以前から書いていますが、XPathやXSLTでは、自分の意図する型に明示的に変換して、暗黙の型変換は可能な限り避けるべきだと思います。James Clarkあたり以外。