DOM XPathの実装に、どこか違和感がある。その理由はこうだ。
典型的なXHTMLの場合、HTML要素に、無名の名前空間とでもいうべきものを指定する。(規格を逆さにしてみても、どうもこの名前のない名前空間の正式名称は分からない)
<html xmlns="http://www.w3.org/1999/xhtml" >
これは確かに名前空間だが、とくに具体的な名前を使ってはいない。したがって、そもそも典型的なXHTMLには、名前空間のプレフィクスなど指定しようがないのである。指定しようがないのだから、XPathEvaluator.createNSResolver(document.documentElement)を使って、現在のドキュメントのResolverを作ったとしても、動くわけがない。だから、XPathにおいては、ダミーの名前空間を指定し、そのダミーの名前空間に対して、XHTMLの名前空間を返すResolverを実装するという、不思議なコードを書かなければならないのだ。
具体的に言うと、XPath表現がこんなものだとしても、
/お前は俺を怒らせた:html/だが断るッ!:body/貧弱ゥ貧弱ゥ:p/*
以下のようなResolverを渡せば動いてしまうのである。
var NSResolver = { lookupNamespaceURI : function (prefix) { return document.documentElement.namespaceURI ; } } ;
なぜなら、このXPath表現はXHTMLに適用することを前提にしているので、名前空間などどうでもいいのである。ただし、名前空間の指定を省略することはできない。どんな文字列でもいいが、何かしら指定しなければならない。なんと無意味なことか。
そもそも、何でこんな不思議な実装になっているのだろう。名前空間が無名なのだから、何も指定する必要はないと思うのだが、よく分からない。
名前空間に名前はあります。 xmlns で接頭辞を決めるのは別名を付けるということに過ぎないと考えるべきです。 C++ 的に書くなら namespace prefix = namespaceURI; といったところでしょうか。
ReplyDeletexmlns= とした場合というのは using namespace ~; みたいなもので、無名なわけではありません。 接頭辞を書かなければ自動的にそれが選ばれる、ということです。 なので、「デフォルト名前空間」という言葉で呼ばれることもあるようです。 根拠となる規格があるのかどうかはわかりませんが。
C++ と違ってタグ名として直接に名前空間URI (別名であるところの接頭辞でなく) まで含めたフルネームを書けないのはおそらく冗長にならないように配慮したのではないでしょうか。
接頭辞を API レベルで見せるのは不格好な仕様だとは思います。 接頭辞と名前空間URIの結び付きはアプリケーションが決めることではなく、 XML 文書が持っている情報なはずだからです。 そして、接頭辞は表記上の便宜であり、扱いたい情報は名前空間URIだからです。
とは言え、名前空間URIと接頭辞の対応を XML 文書の外で (メタ情報として) 持っている場合もあるという困った事情があるので、そこらへんをなんとか出来る方法を用意しようとして現在のようになってしまったのではないかと推測します。 結局のところ、より広汎に対応しようとすると不格好なところが出てくるということです。
「XML 名前空間」で検索してすると最初に出てくるサイト (http://www.kanzaki.com/docs/sw/names.html) を見ると、 MathML を xhtml の中に入れる例があります。 デフォルト名前空間を途中で上書き (シャドウイング) しています。 名前空間の扱いを曖昧にすると問題がありそうなケースのひとつでしょう。
xpath の規格 (http://www.w3.org/TR/xpath) の中には default namespace という表現があるようです。
ReplyDeleteこれが正式に定義された言葉なのかは英語がわからなかったので読みとれなかったですが、ググってみるとそこそこ利用例があるので、業界ではだいたい通じるんじゃないでしょうか。
現にXPathを適用したいドキュメントは、デフォルトの名前空間を使用しているわけで、
ReplyDelete汎用的にしようとしたあげく、実際の利用に当たって、とても変な運用をしなければならないAPIとなってますね。
DOM XPathは。
せっかく、XPath自体は強力なのに。