JavaScript-XPathためしたよ

特に何か便利なものできたって訳ではないのだけど、気づいたこととか書いた方が良さそうだから。サイト製作者が普通に利用する分には問題無いようなことだけど、SeaHorseスクリプト作ってる人は気をつけたほうがいいと思った。

var fso = sleipnir.CreateObject('Scripting.FileSystemObject');
var path = sleipnir.ScriptFullName.replace(sleipnir.ScriptName, '');
var file = fso.OpenTextFile(path + "javascript-xpath-latest.js");
var window = _window;
eval(file.ReadAll());

var r = document.evaluate('//div', document, null, 7, null);
alert("div要素の数は" + r.snapshotLength);

FSOでライブラリの中身を読み込んでeval, execScriptってやりやりたいよね。でも、これをJavaScript-Xpathでやるとスクリプト要素の無いページでエラーを吐く。
JavaScript-Xpathでは、

<script src="javascrpt-xpath.js?name1=value1&name2=value2"></script>

みたいな指定で設定を変えて読み込める。多分*1。そのために、"自分自身"のsrcの?以降の文字列を取得しているが、eval, execScriptだとその"自分自身"の取得に失敗する。大抵は問題にならないはずなんだけど、下記のケースでエラーを起こす。

  1. 最後に読み込まれたスクリプト要素が同じようなロジックを持っているとき
  2. スクリプト要素が全く無いページ

1は例えばプヨぷよの日記で試しに最後に読み込まれたスクリプト要素を取得してみると、

http://s.hatena.ne.jp/entries.json?uri=http://d.hatena.ne.jp/Puyo2/20071118/p1&uri=〜

srcはこのようになっていた。これだけならおかしなことにはならないが、ver0.1.8ではさらに

var convigValue = configStringSplited[1];

となっていて、configValueが未定義になっている。そのため、続く

 if (configValue == undefined)

でエラーになる。ただのtypoだからこっちはすぐ修正されると思うけど。
2は、取得した"自分自身"であるスクリプト要素がnullになってしまうため、null.srcへのアクセスでエラーを起こす。本来の利用法ではありえないことなので、利用する側で対処する必要がある。ので、余計な要素を追加することになるが、

var path = sleipnir.ScriptFullName.replace(sleipnir.ScriptName, '');
var jscript = document.createElement("script");
jscript.type = "text/javascript";
jscript.src = path + "javascript-xpath.js";
document.getElementsByTagName("head").item(0).appendChild(jscript);

のようにスクリプト要素として追加してやった方が無難。

*1:ソース見た感じだと