Xpath 入門
[話者] Xpathは重要だと思うので、しっかり会得するまで学習だ。
http://www.atmarkit.co.jp/fxml/rensai/rexml08/rexml08.html
Xpathの最初の初歩には、この記事がわかりやすかった。
[合いの手] 図がわかりやすいね。
ノードには基本的に以下の3つがあるのか。
- element node 要素ノード、ようするにHTMLタグ
- text node テキストノード、ようするにHTMLタグにはさまれた文字列
- attribute node 属性ノード、ようするにHTMLタグ内部に書いてある class="foo" とか id="bar" とかの属性。
テキストノードは要素ノードの下にあるんだね。
[話者] しかしこの記事はXSLT入門の一環なので、詳しいことまでは書いてない。
学習のために、こんなサンプルHTMLを作成した。
https://sites.google.com/site/itouhiro/2010/xpathtest01.html
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja" lang="ja"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Xpath test</title></head><body><div id="saiyan">バーダック<div class="younger">カカロット<div class="elder">孫悟飯<div>パン</div></div><div class="younger">孫悟天</div></div><div class="elder">ラディッツ</div></div></body></html>
[合いの手] HTMLに改行がないよ。横に長すぎ。
[話者] 1行にしたのは、改行を入れると無駄なテキストノードが増えて学習のジャマになるから。
改行を入れると、次のようになるよ。
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja" lang="ja"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <title>Xpath test</title> </head> <body> <div id="saiyan"> バーダック <div class="younger"> カカロット <div class="elder"> 孫悟飯 <div> パン </div> </div> <div class="younger"> 孫悟天 </div> </div> <div class="elder"> ラディッツ </div> </div> </body> </html>
さっきの記事
http://www.atmarkit.co.jp/fxml/rensai/rexml08/rexml08.html
の図のように表示するなら、
こんな構造だ。
[合いの手] ふむふむ。
[話者] このDOMツリーを、Xpathで自由自在に選択したり値を取り出そう。
http://d.hatena.ne.jp/itouhiro/20101218 の環境、Firefox + FireBugで実行しているよ。
この画像では3つの命令を実行している。$x(' ')
で挟まれた部分が命令本体だ。
まず、最初の命令。
ルートノードを表示。
/
上の画像をよく見てくれ。$x('/')
のところで、この「/
」を実行しているよ。その結果は Document xpathtest01.html
となっているな。
ルートノードの下に何があるか?
/node()
このnode()というのは、規格書
http://www.w3.org/TR/1999/REC-xpath-19991116/
に書いてあるけど、
- element node 要素ノード
- text node テキストノード
のどちらのノードも選択するよ。
上の画像の出力結果にある DocumentType { }
というのは、HTMLの中に書かれた <!DOCTYPE のことらしい。なにも意味ある内容はないので、ここは見ないことにしよう。出力結果は2つあって、もう一つは html
だね。
[合いの手] じゃあ、html っていうのが「ルートノードの下にあるノード」か。
[話者] それを最上位ノードとか、ルート要素とかいうってさっきの記事に書いてあったな。
これは<html>タグのことだし、「要素ノード」だな。
ルートノードの下にある、最上位ノード。
/html
[合いの手] これはさっきの「/node()」と同じものを選んだだけだよね。
[話者] そうだよ。
最上位ノードの下に何があるか?
/html/node()
[合いの手]上の画像見ると head と body という二つの要素ノードがある。
[話者] bodyタグの下に何があるか?
/html/body/node()
[合いの手] <div>タグがあるね。div#saiyan っていうのは、CSS(スタイルシート)と同じで、id="saiyan" と指定してあるdivタグってことか。
[話者] 「bodyタグの下のdivタグ」の下に何があるか?
/html/body/div/node()
[合いの手] おっ、テキストノードがあった。
[話者] ちなみに、テキストノードなしで、要素ノードだけ表示するには node() の代わりに * を使う。
/html/body/div/*
[合いの手] ふーん。
[話者] 逆に、テキストノードだけ表示するには text() を使う。
/html/body/div/text()
「bodyタグの下のdivタグ」の下のdivタグの下には何がある?
/html/body/div/div/node()
[合いの手] あれ、図と比べたらわかるけど、2つの、親の違う子ノードが混ざっているよ。
[話者] どっちも親ノードが<div>タグだから混ざるんだな。
[合いの手] カカロットのほうの<div>だけ表示するにはどうすればいいんだろう。
[話者] 2つのやり方を紹介する。
1. HTMLファイルの中で出てきた順番で指定する方法
/html/body/div/div[1]/node()
最初に出てきた<div>タグを div[1] で、次に出てきたのは div[2] と指定すればいい。
2. <div>についている属性で指定する方法
2つある<div>タグには、兄貴(elder)と弟(younger)というclass属性がついているので、それを利用する。
/html/body/div/div[@class="younger"]/node()
[合いの手] そうなのか。
[話者] あと、このXMLだともう一つやり方を思いついた。
/html/body/div/div/div/div/node()
ここまで<div>タグを掘り下げるとパンちゃんしかいなくなる。
そのあとで、<div>タグをさかのぼっていくと、パンちゃんの親の親であるカカロットの<div>タグだけを選択することができるぞ。
/html/body/div/div/div/div/../../node()
[合いの手] いろいろ、やりようはあるってことね。
[話者] さて、ここまで学んできたのは「絶対ロケーションパス」というものだった。ルートノードから順に下に向かって、ノードをたぐっていくやり方ね。
次に「相対ロケーションパス」というのを学ぶよ。
//div
とすると、階層に関係なく、<div>タグをすべて選択できるのだ。
[合いの手] まあ。
[話者]
//div[@id]
とすると、<div id="abc"> みたいに id属性のある<div>タグだけを選択できる。
//div[not(@id)]
とすると、id属性のない<div>タグだけ選択できる。
//div[@class="elder"]
とすると、兄貴キャラ(<div class="elder">)の<div>タグだけ選択できる。
//div[@class="elder"]/text()
とすると、兄貴キャラの名前がわかる。
[合いの手] こっちのほうが使いやすそうだな。
[話者] ここまで学べば、あとは以下のリンクを見て自習できるんじゃないかな。
- JavaScript-XPath をリリースしました!さあ、あなたも XPath を使おう!(解説付き) - IT戦記
http://d.hatena.ne.jp/amachang/20071112/1194856493 - XPath入門、実用例 - 素人がプログラミングを勉強するブログ
http://d.hatena.ne.jp/javascripter/20080425/1209094795 - XPath使いのための日本語チートシート
http://aoproj.web.fc2.com/xpath/ - AutoPagerize Wiki: XPath Cookbook
https://autopagerize.jottit.com/xpath_cookbook - google:xpath
[JavaScript][Web] Xpathの学習(2) GM「linkify」を解読
http://d.hatena.ne.jp/itouhiro/20101228
に続きます。