Jintrick.netagenda2005年10月アーカイブ → 2005年10月20日

selectNodesメソッド実装

ここで書いてみた_XPathNSResolverも使って、MSXMLでNodeインターフェイスに定義されているselectNodesメソッドを実装してみた。Firefox用のHTMLアプリケーションで利用している。

(function(__proto__/* Node.prototype */){

var resolver = (
	Document.prototype.xpathNSResolver = new _XPathNSResolver({}, null)
);

__proto__.selectNodes = function(expression){
	var doc = this.nodeType == Node.DOCUMENT_NODE ? this : this.ownerDocument;
	var result = doc.evaluate(
			expression, // XPath expression
			this, // Context node
			resolver, // Name space resolver
			XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, // Result type
			null // XPathResult if reuse
		);
	if (result.snapshotLength == 0) return null;
	var nl = new _NodeList(result);
	return nl;
};

__proto__.selectSingleNode = function(expression){
	var doc = this.nodeType == Node.DOCUMENT_NODE ? this : this.ownerDocument;
	var result = doc.evaluate(
			expression,
			this,
			resolver,
			XPathResult.FIRST_ORDERED_NODE_TYPE,
			null
		);
	return result.singleNodeValue;
};

function _NodeList(result){ // 「死」んでいる点に注意する
	this.__result = result;
	this.length = result.snapshotLength;
}
_NodeList.prototype.item = function(index){
	return this.__result.snapshotItem(index);
};


})(Node.prototype);

MSXMLとの違いをメモしておく。selectNodesメソッド、selectSingleNodeメソッド共に、与えたXPath式が不正ならXPathExceptionインスタンスが投げられる。codeプロパティはXPathException.INVALID_EXPRESSION_ERR。評価結果がノード集合にならない場合も同様で、codeプロパティはXPathException.TYPE_ERR。戻り値のノード集合はNodeList型と言いたいところだが、文書の変更が反映されない偽者。名前空間接頭辞の登録は、doc.xpathNSResolver.registerPrefix(prefix, namespaceURI)。変数docはDOM Document。この辺りあまり考えてない。改善の余地あり。

DOM3 XPathって欲張りすぎている気がする。DOMでXPath使ってブール値なんかを直接得ようと思うかな? 殆どの場合得たいのはノード集合だろう。例えば、boolean(self::*)なんて式を評価したいと思うかってこと。まああるだろう。あるだろうけど、それを実現する為にXPathResultなんていう玉虫色のインターフェイスを抽象的に理解するくらいなら、self::*を評価してノード集合(DOMならNodeList型に変換)を得て、こちらで用意したXPathのboolean関数に相当するプロセスに渡した方が良いような。勧告までのスピードって結構大切なんだろうし、XPath全体を含めて抽象化するのではなくて、取りあえずLocation Pathだけ考えてくれれば良かった。その後でニーズがあれば幾らでもごちゃごちゃやりゃいいじゃねえか。


webmaster@jintrick.net
公開: 2005年10月20日
カテゴリ: Javascript ,XPath