よく、以下のように 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 を書いてみた
以下で試せます
コードはこちら
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);
まとめ
急いでコードを書いているときは忘れがちですが。
「文脈」と「任意のデータ」があれば、やっぱりそこにはエスケープの必要性があるということを忘れてはいけませんね