IT戦記

プログラミング、起業などについて書いているプログラマーのブログです😚

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 を書いてみた

以下で試せます

http://amachang.sakura.ne.jp/misc/xpath_escape/ ←クリック!

コードはこちら
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);

まとめ

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