まめ畑

ゆるゆると書いていきます

javascriptでXPath使ってみた

最近、Javascriptの勉強を始めてこまごまとグリモンを書いているのですが、JavascriptXpathを使う時の超基本的メモ。
Introduction to using XPath in JavaScript - MDCで勉強した。

基本的な使い方

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

この関数は、XPath式を評価しXPathResultオブジェクトを返してくる。
XPathResultオブジェクトは単一のノード、もしくはノードの集合。
との事。


なにやら引数が多いな。

引数

  1. xpathExpression: XPath式。
  2. contextNode: XPath式を評価する対象となるノード。よく使われるのはdocumentらしい。局所的に使いたいならその箇所を対象にした方が検索対象少なくなるからいいのかな?それとも、速度はあまり変わらないのか?
  3. namespaceResolver: XPath式に含まれるあらゆる名前空間接頭辞を渡され、その接頭辞に対応する名前空間URIを表す文字列を返す関数。
    1. XPathEvaluator オブジェクトのcreateNSResolverメソッドにより作成されたもの。ほとんどの場合はこれを使うべきらしい。
    2. HTML 文書の場合や、名前空間接頭辞が使われていない場合は null 。XPath式に名前空間接頭辞が含まれている場合にnullを使うと、NAMESPACE_ERRコードと共に DOMExceptionが投げられる。
  4. resultType: 戻り値のタイプ。もっとも良く指定される定数はXPathResult.ANY_TYPEらしい。
  5. result: 既存のXPathResultオブジェクトまたはnullを指定します。XPathResultオブジェクトが指定された場合にはそのオブジェクトが再利用される。 nullが指定された場合には新しいXPathResultオブジェクトが生成される。


namespaceResolverって名前空間接頭辞とURIをマッピングする関数という認識でいいんかな?
HTMLではnull。


result typeは戻り値を指定する。単純型とコレクション型がある。

  • 単純型
    • resultTypeが
    • NUMBER_TYPE 倍精度浮動小数点数
    • STRING_TYPE 文字列
    • BOOLEAN_TYPE 真偽値
    • 以下の時は結果オブジェクトのプロパティから取得できる。
    • numberValue
    • stringValue
    • booleanValue


注意書きが「JavaScript では数値を表示しようとすると文字列に変換されますが、XPathインターフェイスはstringValueプロパティを要求しても数値の結果を自動的に変換しない」
これは覚えておこう。

  • コレクション型

この中でイテレータしか聞いた事ないな。
でも、勉強してる中でスナップショットは良く見る。

を指定した場合。

戻り値がイテレータのように振舞うから、iterateNext()メソッドで次の要素を取り出せる。
要素が無くなるとnull。


ここにも注意書きが「反復処理中に文書が変異した(文書ツリーが改変された)場合、反復処理は無効化され、XPathResultのinvalidIteratorStateプロパティが trueに設定され、NS_ERROR_DOM_INVALID_STATE_ERR例外が投げられます」

ループ中でノードの追加とか削除とかはするなということか。

  • スナップショット
    • UNORDERED_NODE_SNAPSHOT_TYPE
    • ORDERED_NODE_SNAPSHOT_TYPE

マッチしたノード集合となり、XPathResultオブジェクトのsnapshotItem(itemNumber) メソッドによってそれぞれのノードにアクセス出来る。itemNumberは取り出すノードのインデックス。含まれるノード数はsnapshotLengthプロパティを使う。

イテレータと違ってループ中にツリー構造が変更されてもエラーは出ないのか。
なるほど、その時点のツリー構造をとってくるのか。
でも、今現在の構造との対応がないから変化している可能性がある。

  • ファーストノード
    • ANY_UNORDERED_NODE_TYPE
    • FIRST_ORDERED_NODE_TYPE

最初に見つかったノードを返す。
UNORDEREDだと、順番は保障されない。
singleNodeValueプロパティでアクセスする。

  • ANY_TYPE

結果型がANY_TYPEである場合、式を評価した結果から導き出される適切な型になる。
返される結果型は単純型のうちのいずれになる。
コレクション型であった場合、UNORDERED_NODE_ITERATOR_TYPEにしかならない。


定数の一覧は、参考ページにまとまってます。

まとめ

なるほど。結構簡単に使える事が判明。
XPathは普段使っているので、今回はJSでの使い方について調べた。

スナップショットを使う例が多いのは、変更されても問題が無いからか?
ここはもっと調べる。
なんかJS楽しくなってきたぞ。

  • おまけ

グリモン作ってて日本語使うと文字化けしたので、調べたらエンコードしないとダメらしい。
こんまめ→\u3053\u3093\u307E\u3081
の様な感じ。これUTF-16なの?

Text Escaping and Unescaping in JavaScriptが大変便利。