|
|
||
CSS、HTML、XHTML、XML、DOM、XSLT、XPath、ECMAScript、Python、ウェブユーザビリティ、その他に関連する文書等のリソースを挙げていったりします。より本質的な議論を志向。
注意:Hatena::agendaの更新は終了しています!過去の記事はagenda のホームページよりどうぞ。今後の更新情報の取得は、agendaのフィード(XML/Atom)から。
北村さんが引用している仕様書の箇所を読んだら、true() != foo(fooは空のノード集合)は真であると気づきました。この時は各ノードではなくてノード集合foo自身にboolean関数が適用されるようです(true() != false()で真)。MSXML4.0は正しかった。4Suiteの実装が間違い。でも片方がブール値の時だけ処理が違うというのも一貫性が無くて混乱の元だし、Ogbujiさんを責める気にはなれません。私も勘違いしていたわけだし。一応原文もチェック:
If one object to be compared is a node-set and the other is a boolean, then the comparison will be true if and only if the result of performing the comparison on the boolean and on the result of converting the node-set to a boolean using the boolean function is true.
3.4 Booleans(XML Path Language (XPath))より
ふと気づいて青い本(謎)を調べたら、やっぱり勘違いしていました。
ここで挙げられている問題について、分かりやすく説明する為に更に条件を絞り込んでみました。fooは空のノード集合です。
self::* != foofoo != foo3 != foo'あ' != foo以上、全部偽でした。つまり空のノード集合は、ブール値以外の何と比較しても必ず偽でした。
true() != fooMSXMLでは、このようにブール値と比較したときには、予想通りの結果が得られます。真です。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あたり以外。