Jintrick.netagenda2003年02月アーカイブ → 2003年02月24日

XSLTクイズ from Micah Dubinko さん(NaNのXPath表現)

XSLTクイズをやってみました。

XML:
<snipsnap>
<snip>
<name>'2003-02-22</name>
...
</snip>
</snipsnap>

XSLT:
...
<template match="snip[number(substring(name,1,4))!=NaN]">...

http://dubinko.info/blog/2003_02_23_archive.html より

「子要素nameの(集合の)string-valueの1文字目から4文字目までを抜き出したものを引数にしたnumber関数の戻り値が、非数値(NaN)にならないsnip要素」にマッチさせるテンプレートのつもりなのでしょう。この誤りを指摘せよというクイズです。

まずこの比較式の右辺の「NaN」は、非数値(NaN)としてでなく、ノード集合として評価されてしまう筈です。

問題は、その「非数値」というデータ型を、XPathでどうやって表現するのかという点だと思います。私は明示的な方法を知りませんでしたので仕様書を見るという「カンニング」をしたところ、非数値(NaN)を返す関数が特別に用意されているわけではないようです。また、非数値(NaN)は、XPathではNumberのデータ型の特殊な形態であるということも分かりました。

結果的に非数値(NaN)を返す関数なら複数あります。最もシンプルそうなものはstring型のデータを引数にしたnumber関数でしょうか。

<template match="snip[number(substring(name,1,4)) != number('a')]"          />

と、これで終了の予定だったのですが、MSXML君は両者を異なるオブジェクトと解釈するようです。仕様書を見てもNaN同士の比較についての記述を発見できませんでした。でもNaNは数値の一種なのですから……不具合?

<template match="snip[string(number(substring(name,1,4))) != string(number('a'))]"          />

'NaN'という文字列同士の比較にすることで解決。XSLTを無理矢理に妥当性検証プロセッサとして使う時に役立つかもしれません。他のプロセッサではどうでしょう。

でも本当に非数値を明示的に表すXPath表現って無いのでしょうか。isNaN()みたいなブール値を返すものも無いようですし。何やら気持ちの悪いものがあります。

2.の答えが待ち遠しい。もしかして、ああいう形式の「質問」だったりして……1.はまさかとは思いますが。


webmaster@jintrick.net
公開: 2003年02月24日
カテゴリ: XPath ,XSLT