読者です 読者をやめる 読者になる 読者になる

すがブロ

sugamasaoのhatenablogだよ

若手IT勉強会(第9回)のメモ

本日の勉強会のダイジェスト(2009/06/29追記)

今日の勉強会の場所

主に、以下の本を読んだりする会です。

JavaScript 第5版

JavaScript 第5版

21.4 章の XPath について

メモ。正確ではないかもしれません。
FireFoxでは(IE以外では?) XML Path の操作は html に対しても行える。
以下の例は XPath 式をコンパイルしない場合。コンパイルして再利用する場合は evaluate じゃなくて createExpression を使う。

var ret = document.evaluate("count(//h2)", document, null, XPathResult.NUMBER_TYPE, null).numberValue
console.log(ret)
// h2 の数を count 関数で計算してる

var ret = document.evaluate("//h2[1]", document, null, XPathResult.STRING_TYPE, null).stringValue
console.log(ret)
// h2 の文字列を出力

document.evaluateの仕様(Mozila)

var xpathResult = document.evaluate( xpathExpression, contextNode, namespaceResolver, resultType, result );

このパラメータの詳細は以下のようになっている。

  • xpathExpression: 評価する XPath 式を文字列で指定します。
  • contextNode: xpathExpression を評価する対象となる文書内のノードを指定します。指定されたノードの全ての子ノードに対しても評価が行われます。もっともよく指定される値は document です。
  • namespaceResolver: xpathExpression に含まれるあらゆる名前空間接頭辞を渡され、その接頭辞に対応する名前空間 URI を表す文字列を返す関数です。この関数により、XPath 式で使われている接頭辞と文書内で使われている接頭辞が異なっていたとしてもそれを変換する事が可能になります。この関数は次のいずれかです。
    • XPathEvaluator オブジェクトの createNSResolver メソッドにより作成されたもの。ほとんどの場合はこれを使うべきでしょう。
    • HTML 文書の場合や、名前空間接頭辞が使われていない場合は null 。xpathExpression に名前空間接頭辞が含まれている場合に null を使うと、NAMESPACE_ERR コードと共に DOMException が投げられるので注意してください。
    • ユーザ定義のカスタム関数。詳しくは付録のユーザ定義名前空間リゾルバの使用の節を参照して下さい。
  • resultType: 評価の結果返してほしい値の型を示す定数です。もっとも良く指定される定数は XPathResult.ANY_TYPE で、この場合、指定された XPath 式に対して一番適切な型で結果が返されます。指定できる定数の一覧は付録の定数一覧の節を参照してください。それぞれの定数の使い方は戻り値の型の指定の節を参考にしてください。
  • result: 既存の XPathResult オブジェクトまたは null を指定します。 XPathResult オブジェクトが指定された場合には、そのオブジェクトが再利用されます。 null が指定された場合には新しい XPathResult オブジェクトが生成されます。

なので、先ほど例にあげたスクリプトは以下のような意味になります。

document.evaluate(
  "//h2[1]", // XPath の文字列(ここをいわゆる xpath と呼ぶ)
  document,  // どこを基点として XPath を演算するか
  null,      // namespace とかを指定する(指定する/しないで何か違うの???)
  XPathResult.STRING_TYPE, // 戻り値の型を指定
  null       // 戻り値を新しいオブジェクトとして使うか?(nullだと作る)
)
XPath で ID 指定
var result = document.evaluate(
'id("comment-form")',
document,
null,
7,
null);

console.log(result.snapshotLength)
console.log(result.snapshotItem(0))
コンパイルして evaluate
var exp = document.createExpression(
  "//p", // XPath
  null   // namespace
)
exp.evaluate(
  document,  // どこを基点とするか
  XPathResult.STRING_TYPE, // 戻り値の型を指定
  null       // 戻り値を新しいオブジェクトにする?
).stringValue

こんな感じにすると、 exp 自身を使い回しができます。・・・たぶん、ある程度複雑な XPath の指定をするとき等には速度面で影響がでてくるのではないでしょうか*1

今まで Firefox の話ばかりでしたね

IE だとどうすんの? という意見もあるのですけど、そこは JavaScript-XPath をリリースしました!さあ、あなたも XPath を使おう!(解説付き) - IT戦記 を使えば良いのでは、と思います!><

*1:よくわかってない