Hatena::ブログ(Diary)

IT戦記 このページをアンテナに追加 RSSフィード Twitter

2009-09-17

XPath に文字列を埋め込むときの注意

よく、以下のように XPath文字列を埋め込む事があります

document.evaluate('//*[@class="' + text + '"]', document, null, 7, null);

まあ、僕もよくこんなコード書くんですけど。

でも、これって

text が外部から来るものだったら、意図通りの動作をしないんですよね

たとえば、以下のような例です。

var text = '"] | /hoge/fuga/piyo | .["';
document.evaluate('//*[@class="' + text + '"]', document, null, 7, null);

というわけで

任意の文字列XPath の式に変換する JavaScript を書いてみた

以下で試せます

404 Not Found ←クリック!

コードはこちら
function escapeXPathExpr(text) {
    var matches = text.match(/[^"]+|"/g);

    function esc(t) {
        return t == '"' ? ('\'' + t + '\'') : ('"' + t + '"');
    }

    if (matches) {
        if (matches.length == 1) {
            return esc(matches[0]);
        }
        else {
            var results = [];
            for (var i = 0; i < matches.length; i ++) {
                results.push(esc(matches[i]));
            }
            return 'concat(' + results.join(', ') + ')';
        }
    }
    else {
        return '""';
    }
}
以下のように使います
document.evaluate('//*[@class=' + escapeXPathExpr(text) + ']', document, null, 7, null);

まとめ

急いでコードを書いているときは忘れがちですが。

「文脈」と「任意のデータ」があれば、やっぱりそこにはエスケープの必要性があるということを忘れてはいけませんね