Introduction

ブログ内検索

  • このサイトの記事を検索 by Google

おすすめの一冊!

無料ブログはココログ

« KlogShow を日本語対応に | トップページ | KlogShow を完全透過に »

2010-05-19

xyzzy で XML を解析


TL を眺めていたら、xyzzy で XML を処理しようとしているひとがいたので、
前に自分の書いたコードを発掘してきました。

xml-parser-modoki というライブラリを使います。

  ⇒ http://www7a.biglobe.ne.jp/~hat/xyzzy/dl.html#xml-parser-modoki

アーカイブに含まれている xml-parse-modoki.l を site-lisp/ の下に置いて、
バイトコンパイルしておきます(念のため)。

あとは、以下のようなコードで利用できます。

(defun xmlpm-parse-with-input-buffer (target)
  (save-excursion
    (switch-to-buffer target)
    (xmlpm-parse)))

(defun xmlpm-parse-string (s)
  (save-excursion
    (let ((tbuf (create-new-buffer "*xmlpm*")))
      (switch-to-buffer tbuf)
      (with-output-to-selected-buffer
        (format t "~A" s))
      (let ((result (xmlpm-parse)))
        (delete-buffer tbuf)
        result))))

;;====================

(defun www-get (url query)
  (let ((res (xhr-get url :query query)))
    (let ((status (xhr-status res)))
      (case status
        (200 (let ((xml (xhr-response-text res)))
               (output-to-buffer "*response*" xml) ; for debug
               (let ((lst (xmlpm-parse-string xml)))
                 (unless lst
                   (output-to-buffer "*xml*" xml)
                   (error "ERROR: invalid response for GET"))
                 lst)))
        (t   (error "ERROR: unexpected response"))))))


(labels ((rec (url user cursor acc)
           (let ((query (list :cursor cursor)))
             (when user
               (if (string-match "^[0-9]+$" user)
                   (setf query (nconc query (list :user_id user)))
                   (setf query (nconc query (list :screen_name user)))))
             (let ((lst (www-get url query)))
               (if (not lst)
                   nil
                   (let ((users (cddr (nth 2 (car lst))))
                         (next (third (nth 3 (car lst)))))
                     (if (equal next "0")
                         (nconc acc users)
                         (rec url user next (nconc acc users)))))))))
  (defun api-friends (&optional user)
    (let ((url (concat *base-url* "statuses/friends.xml")))
      (rec url user -1 nil)))
  (defun api-followers (&optional user)
    (let ((url (concat *base-url* "statuses/followers.xml")))
      (rec url user -1 nil))))
XML と S 式は親和性が高くて、リスト操作関数を使えば 各要素に簡単にアクセスできます。とっても便利。 ちなみに、上記コードは Twitter API を叩くプログラム (「いつふぉろ」のクローラ)の一部です。 今のクローラは Perl なんですけどねー

« KlogShow を日本語対応に | トップページ | KlogShow を完全透過に »