さくらんぼのlambda日記

lambdaちっくなことからゲーム開発までいろいろ書きます。

LispでXMLを使いたい part2

前回説明するといって放置したやつを再度。
XMLを扱うだけならば、cxmlを使うのがお手軽。
グーグル先生に聞くとcXMLという規格があるようでドキュメントが見つかりづらい。
Closure XMLというのが正式名称らしいのでそちらでググった方が良い。

公式サイトはここ。http://common-lisp.net/project/cxml/
大体の使い方はQuick-Start Exampleで確認できる。

YahooのXMLを読んでみる

Yahooの開発者ベージにXMLのサンプルが乗っている。
http://developer.yahoo.co.jp/search/rest.html

このドキュメントのURLの構築の項の例を使う。

http://api.search.yahoo.co.jp/WebSearchService/V1/webSearch?appid=YahooDemo&query=finances&format=pdf

これが返すXMLファイルをパースしようと思う。
テストの為にこのファイルを保存しておく。

XMLファイル読み込み

検索結果をexample.xmlに保存しておく

(cxml:parse-file "example.xml" (cxml-dom:make-dom-builder))
#<RUNE-DOM::DOCUMENT {12FC2A31}>
(defparameter *example* *)
*EXAMPLE*

DOMのツリーとして読み込めた。

(dom:document-element *example*)
#<DOM-IMPL::ELEMENT test @ #x722b6ba2>

(dom:tag-name (dom:document-element *example*))
"test"

(dom:child-nodes (dom:document-element *example*))
#(#<DOM-IMPL::ELEMENT child @ #x722b6d8a>)

(dom:get-attribute (dom:document-element *example*) "a")
"b"

このようにデータをいじっていける。
先ほどのデータの場合だと
非常に複雑になってしまうのだが。

CL-USER> (aref (dom:child-nodes 
	 (aref (dom:child-nodes 
	 (aref (dom:child-nodes (dom:document-element *example*)) 5)) 0)) 0)
#<RUNE-DOM::TEXT {13819121}>
(dom:node-value  (aref (dom:child-nodes (aref (dom:child-nodes (aref (dom:child-nodes (dom:document-element *example*)) 1)) 0)) 0) )
"L'évolution des finances publiques"

これで要素の値を取得することができる。
しかし、arefとかでアクセスしていくのは分かりづらい。
Lispのリストに変換もできるので試してみる。

(setq xml-data (cxml:parse-file "example.xml" (cxml-xmls:make-xmls-builder)))
(nth 2 (nth 2 (nth 3 xml-data)))
"PUBLIC FINANCES IN QUÉBEC, CANADA ..."

どう考えてもこっちが楽そう。
もちろんアクセスする方法は色々考えられそうなので適当に。