sxpathが分かりにくかった
sxpathが分かりにくかったのでメモ。
使い方
まず、sxpathは関数を返す
gosh> (sxpath '()) #<closure (sxpath loop)>
ので使うときはこんな感じになる。(以下でshtmlはSHTMLデータとする)
(use sxml.sxpath) ((sxpath '(html head title)) shtml)
クエリ
上で'(html head title)としたようにクエリを与えて目的のデータを取得する。
この例だと「html要素の直下にあるhead要素の直下にあるtitle要素」を取得できる。
他にも
((sxpath '(// (div (@ class (equal? "hoge"))) *)) shtml)
でshtml内の、「class属性の値がhogeであるdiv要素の全ての子ノード」を取得できる。
記号の意味はそれぞれ、
- //:そのノード自身と全ての子孫ノード
- @:属性リスト
- *:任意の要素(属性リストやテキストノードは含まない)。
また、括弧で条件が指定できて、上の例だと
「全てのノードを取り出す(//)」→「その中でdiv要素なものを取り出す」→「その中でclass属性を持つものを取り出す」→「その中で値がhogeであるものを取り出す」
の様に適用されている。
(「sxpathがとてもわかりにくい - 再帰の反復blog」で丁寧に解説されている)
XPath
クエリにはXPathを使うこともできる。
SXPathと比較して書くと以下の様になる。
; SXPath ((sxpath '(// (div (@ id (equal? "content"))))) shtml) ;XPath ((sxpath "//div[@id='content']") shtml) ; SXPath ((sxpath '(// h2 *text*)) shtml) ;XPath ((sxpath "//h2/text()") shtml) ; SXPath ((sxpath '(// (div (@ title)) *text*)) shtml) ;XPath ((sxpath "//div[@title]/text()") shtml) ; SXPath ((sxpath '(// (div (@ class (equal? "problem_content"))) *)) shtml) ;XPath ((sxpath "//div[@class='problem_content']/*") shtml)
個人的にはXPathの方が読みやすいので好み。