Posted at

CommonLispでjQueryのようなDOMアクセスを行う方法

More than 5 years have passed since last update.

CommonLispにはHTMLのparseを行うライブラリは様々あります。

http://www.cliki.net/HTML%20parser

がjQueryのようなcssでセレクタを指定する形式のものとして

stp-queryというライブラリをquicklispを眺めていたら見つけたので簡単に使い方をメモしておきます。


stp-query.lisp

(ql:quickload "drakma")

(ql:quickload "stp-query")
(ql:quickload "jp")
(ql:quickload "cxml-stp")

;; "->" マクロで利用している関数
;; どこ由来の関数なんだろう...?
(defun ensure-list (thing)
"Returns THING as a list.

If THING is already a list (as per listp) it is returned,
otherwise a one element list containing THING is returned."
(if (listp thing)
thing
(list thing)))

;; jQueryのようにチェインしたいのでマクロを定義
;; stp-queryの作者のbackportsリポジトリより拝借
(defmacro -> (x &rest forms)
"Threads X through FORMS in second postition."
(if (null forms)
x
`(-> ,(let ((list (ensure-list (first forms))))
(list* (first list) x (rest list)))
,@(rest forms))))

;;
;; drakmaでWebページを取得してcxml-stpのツリーに変換
;; その内容を$:findで検索してみる
;;
;; アクセス先はさくらんぼ亭の公式Web
;;
(let* ((web-page (ql:quickload "stp-query")
(parsed-doc (chtml:parse web-page (cxml-stp:make-builder)))
(-> ($:find parsed-doc "li") ($:find "a"))))


こんな感じでjQueryのようにDOMを取得できます。