Home About Contact
Emacs , Emacs Lisp

Emacs Lisp JSON 文字列のパース

ハイパーリンクのつくり方がわかったので サーバから取得した JSON に記述されている 名前とURL の一覧情報から ハイパーリンクの一覧情報をつくろうと思う。

次のような JSON データがあったとして、これをパースして、 Emacs のバッファにボタン(ハイパーリンク)をつくる lisp を書きたい。

{
  "list": [
    {
      "name": "google",
      "url": "https://www.google.co.jp/"
    },
    {
      "name": "apple",
      "url": "https://www.apple.com/"
    }
  ]
}

JSON 文字列のパース

このページ https://www.gnu.org/software/emacs/manual/html_node/elisp/Parsing-JSON.html を見ると、 json-parse-string という関数が書いてある。 ただ使い方がよくわからない。

代わりに json-read-from-string を使ってみる。

(require 'json)
(json-read-from-string "{\"list\": [1, 2, 3]}")

foo.el ファイルなどでこれを記述して C-x C-e する(それぞれの行で)。 するとミニバッファに次が出力される。

((list . [1 2 3]))

これは (list . [123]) という key-value のオブジェクトがひとつだけ入ったリストになっているので、 たとえば、 elt を使って先頭の要素(オブジェクト)を取り出す。

(elt
 (json-read-from-string "{\"list\": [1, 2, 3]}") 0)

C-x C-e するとミニバッファに (list . [1 2 3]) が出力される。

または、assq というキーを指定して該当要素をみつける関数を使えば:

(assq 'list
      (json-read-from-string "{\"list\": [1, 2, 3]}"))

C-x C-e すると同じ結果が得られる。

ここから car すれば list が cdr すれば [1 2 3] を得ることができる。

(car (assq 'list (json-read-from-string "{\"list\": [1, 2, 3]}"))) ; => list
(cdr (assq 'list (json-read-from-string "{\"list\": [1, 2, 3]}"))) ; => [1 2 3] 

もう少し具体的な JSON データを考える。

{
  "list": [
    {
      "name": "macbook"
    },
    {
      "name": "mac mini"
    }
  ]
}

これを実行すると(1番目の要素を取得)

(elt
 (cdr (assq
       'list
       (json-read-from-string
        "{\"list\": [{\"name\":\"macbook\"}, {\"name\":\"mac mini\"}]}"))) 0)

これが得られる。

((name . "macbook"))

これを実行すると(2番目の要素を取得)

(elt
 (cdr (assq
       'list
       (json-read-from-string
        "{\"list\": [{\"name\":\"macbook\"}, {\"name\":\"mac mini\"}]}"))) 1)

これが得られる。

((name . "mac mini"))

道程は遠い。

かきかけです。