XPathNSResolver

XPathNSResolver

[1] DOM水準3 で定義されている界面 XPathNSResolver は、 XPath を解釈するに当たって名前空間接頭辞名前空間URI解決する必要が生じた時に呼び出されるメソッド lookupNamespaceURI が定義されている界面です。

[2] 仕様書:

[3] 界面:

[4] NodeXPathNSResolver: DOM水準3Node 界面でも lookupNamespaceURI メソッドが定義されています。 XPathNSResolver のメソッドは Node のメソッドの subset のような定義になっています。 (Node 界面を直接使わないのは、 節点を使わなくても名前空間解決ができるようにするためと、 DOM水準3 中核モジュールの実装がなくても XPath モジュールを使えるようにするためらしいです。)

[5] 接頭辞無しの既定名前空間: XPath 1.0 において名前空間接頭辞が無い QName (既定名前空間) は null名前空間に固定されています。 ですから少なくても XPath 1.0の解釈のために lookupNamespaceURI の引数に null や空文字列が渡されることはなく、渡された場合の結果は未定義とされています DOM 水準3 XPath(Node 界面の同名のメソッドは null が渡された場合の動作も定義されています。)

作成

[6] 節点から作成: XPathEvaluator 界面で定義されている createNSResolver メソッドは、 Node を受け取って XPathNSResolver を作成します。 作成された XPathNSResolver は、 lookupNamespaceURI メソッドが呼ばれたら NodelookupNamespaceURI メソッドを呼ぶような動作をします DOM 水準3 XPath

XML要素内容として書かれている XPathを、その要素における名前空間の束縛に従って解釈する、 というような場面でこの方法で作成した XPathNSResolver を使うと便利そうです。

[7] 節点からキャストで作成: DOM水準3中核モジュールと XPath モジュールの両方に対応した気が利いた (界面の概念を持つ言語での) DOM の実装なら、 DOM水準3Node 界面を実装した物体が XPathNSResolver 界面も実装しているはずです。ですから、

resolver = (XPathNSResolver) document.getElementById ("someElement");

のようなことが (>>6 を使わずに) できるでしょう。

[8] lookupNamespaceURI メソッドを持った物体を作成: に関して弱い言語なら、適当に lookupNamespaceURI メソッドを持つ物体を用意すれば OK です。例えば >>7 にある例は

resolver = document.getElementById ("someElement");

のように特に何もしなくても大丈夫です。また、

resolver = {
  lookupNamespaceURI: function (pfx) {
    switch (pfx) {
      case 'xhtml1': return "http://www.w3.org/1999/xhtml";
      case 'xhtml2': return "http://www.w3.org/2002/06/xhtml2/";
      default:       return null;
    }
  }
};

のような感じで物体を作ってもよいです。

呼び出し順序

[16] ChromeFirefox も、名前空間接頭辞それぞれに対して呼び出します。同じ名前空間接頭辞を複数使ってもキャッシュされたりはせず、毎回呼び出されます。 >>15

[17] ChromeFirefox も基本的にはの前から後ろへと呼び出していきます。しかし同じステップ内で Firefox名前テスト述語の順に呼び出しますが、 Chrome述語名前テストの順に呼び出します。述語が複数ある場合どちらのブラウザーでも前から後ろへと呼び出します。 >>15

[19] 構文エラーがある場合、 ChromeFirefox もその前にある名前空間接頭辞については呼び出しますが、 それ以後の名前空間接頭辞は呼び出しません。 >>18 Firefox字句解析レベルでのエラーがあるとそれ以前の名前空間接頭辞についても呼び出しませんが、 Chrome は呼び出します。 >>20 また Chrome>>17 の通り述語を先に処理するので、述語で構文エラーがあると名前テスト名前空間接頭辞は呼び出されません。 >>21

[23] ChromeFirefox も、 QNameNameTest の全体の構文解析が終わってから名前空間接頭辞について呼び出すようです。

コールバック this 値

[24] Firefox でも Chrome でも Function を指定した場合の callback this value はその関数自体になるようです。

返す値の解釈

[22] ChromeFirefoxnull が返されると document.evaluateNamespaceError を返します。 undefined空文字列を含むその他の値は名前空間URLと解釈するようです。ただし空文字列はどの名前空間とも (null名前空間とも) 一致しません。 例外を投げると FirefoxSyntaxErrorChromeNamespaceError を返します。 (null例外の場合そこで構文解析は終了します。)

歴史

NSResolver

[27] Selectors API ははじめ DOM3 XPath を参照していましたが、かなり初期に自身で NSResolver を定義するようになりました。

メモ

[9] 参考:

XPath モジュール全体の使い方は >>10 を見ればよいでしょう。 >>11>>12 は名前空間の扱いに少々誤解がみられます。

[13] XPath, $X function, NSResolver < 16 < March < 2006 < nulog, NULL::something : out of the headphone (2007-06-09 23:04:20 +09:00 版) http://lowreal.net/logs/2006/03/16/1 (名無しさん 2007-06-09 14:07:18 +00:00)

[14] d:id:quaa ( 版) http://d.hatena.ne.jp/quaa/20070604#p1 (名無しさん 2007-06-09 14:07:44 +00:00)

[25] Chrome では NoInterfaceObject ですが Firefox では window.XPathNSResolver が存在します。

[28] Chromenull が指定された時に Node既定名前空間ではなく、 null を返すようです。この点で NodelookupNamespaceURI を呼び出すのと結果が異なります。 (空文字列だとどちらも null になります。) Firefox はどちらでも null になるので XPathNSResolver で特別な処理をしているのかどうかは観測できません。

[29] Selectors API ( ( 版)) http://dev.w3.org/cvsweb/~checkout~/2006/webapi/selectors-api/Overview.html?rev=1.28&content-type=text/html;%20charset=utf-8#nsresolver-interface

[30] 384003 – XPathEvaluator does not accept a Node as NSResolver ( ( 版)) https://bugzilla.mozilla.org/show_bug.cgi?id=384003

[31] Add the DOM XPath interfaces from the WHATWG wiki (annevk著, ) https://github.com/whatwg/dom/commit/dea5d92156f144faf57d1a5e54a17227139ca3c5