Jintrick.netagenda2002年09月アーカイブ → 2002年09月15日

MS独自拡張selectNodesメソッドについて

selectNodesメソッドは、Nodeインターフェイスに実装されているMSの独自仕様。引数のXPath式で指定されたノード集合が返却される。

実際に非常に役立ったので、具体的な使い方をメモしておく。ちなみにMSXML3.0以前のことは知らない。

将来ノード集合の指定方法を拡張する予定があるのか、面倒なことにXPathを使用することを明言しなければならない。DocumentオブジェクトのsetPropertyメソッドで指定。


var xmlDoc = new ActiveXObject('Msxml2.DOMDocument.4.0');
xmlDoc.async = false;
xmlDoc.load('foo.xml');
xmlDoc.setProperty('SelectionLanguage', 'XPath');

XPathでは、ノードテストにQNameが使われる為、名前空間接頭辞がどの名前空間を指しているかを明示する必要も出てくる。明示には同じくsetPropertyメソッドを使う。

以下は、XHTMLの要素をhtmlという名前空間接頭辞で特定する場合。

xmlDoc.setProperty(
  'SelectionNamespaces',
  'xmlns:html="http://www.w3.org/1999/xhtml"'
);

well-formedなだけで名前空間もnullな謎XML文書を扱う場合には無関係。ノードテストで要素名を使った際、名前空間接頭辞が無い場合、それは名前空間がnullであることを意味するので、例えばxmlns="http://www.w3.org/1999/xhtml"等とデフォルトの名前空間を設定しても無意味。そんなことが出来てしまったら名前空間がnullな要素を特定不可能になってしまう為。

ちなみにasyncプロパティは、デフォルトのtrueのままだと文書実体のロード完了を待ってくれないらしい。一々falseに設定するのが面倒で仕方がないけれども、処理速度を優先したい時にデフォルトがfalseだと非効率なので合理的。

ともあれこれでselectNodesメソッドが使用可能になる。任意のノードのメソッドとして使用可能で、そのノードが、XPathにおけるコンテクストノードとなる。以下はXHTML文書にて、ルート要素(HTML要素/xmlDoc.documentElement)をコンテキストノードとして、body要素の子要素であり、かつ、class属性値が"footer"であるdiv要素全てをノードリストとして変数nlDivsに格納した例。


var nlDivs;
nlDivs = xmlDoc.documentElement.selectNodes(
	'child::html:body/child::html:div[@class="footer"]'
);

XPath式での指定に失敗した場合、空のノードリスト(length == 0)が返却される。

注意点

selectNodesメソッドは、常にノードリストを返却する。


var nAddress;
nAddress = nlDivs.item(0).selectNodes(
	'following-sibling::html:address[1]'
);

と、このように特定の一つのaddress要素を指定したつもりでも、やはりノードリスト型のオブジェクトが返却される。実際にこのaddress要素を取得するには、itemメソッドで、nAddress.item(0)とする。

指定するノードが一つであることが予め分かっているなら、selectSingleNodeメソッドを使った方が明らかにベター。この場合、式で複数のノードが選択されようとも、そのうちの最初のノードが返却される。

その他雑記

というわけで、Weblogの更新記事をカテゴリごとに分類したり色々するために、そりゃあもう恐ろしいほどの作業を全部MSXML君にやってもらうことにした。ついでに更新履歴も。時期によっては、ホームページの更新とログファイルの生成も行わせるので、下手をすると15以上の文書を生成させることに。もしselectNodesメソッドが使えなかったら、嫌になって途中で止めていたような気がする。

「ツリーを辿る」というまどろっこしいことをしないで済むことが多いので、簡単な変換ならXSLTを使うより楽。


webmaster@jintrick.net
公開: 2002年09月15日
カテゴリ: DOM ,Javascript ,XPath