Elisp: JSON. Import, Export.

By Xah Lee. Date: . Last updated: .

What is JSON

Import. JSON String to Lisp Object

json-parse-string

(json-parse-string STRING &rest ARGS)

Convert json string to emacs lisp data structure object.

Rest args specify choices in what type of lisp data structure you want. They are:

  • :array-type OBJ → default to 'array. Can be 'list.
  • :object-type OBJ → default to 'hash-table. Can be 'alist, 'plist
  • :null-object OBJ → defaults to :null.
  • :false-object OBJ → defaults to :false.
;; example of json array
(json-parse-string "[1,2,3]")
;; [1 2 3]

;; example of json object
(json-parse-string "{ \"name\": \"Mary\", \"age\": 24}")
;; #s(hash-table test equal data ("name" "Mary" "age" 24))

;; example of json, mixed array and object
(json-parse-string "[1, { \"name\": \"Mary\"} ]")
;; [1 #s(hash-table test equal data ("name" "Mary"))]

;; example of json special values
(json-parse-string "[true, false, null]")
;; [t :false :null]

Example. Specify Object Type

;; json with duplicate keys
(setq xjson "{ \"a\": 3, \"b\": 4, \"b\": 5}")

;; default to hashtable. last key override
(json-parse-string xjson)
;; #s(hash-table test equal data ("a" 3 "b" 5))

;; to associative list. duplicate keys remain
(json-parse-string xjson :object-type 'alist)
;; ((a . 3) (b . 4) (b . 5))

;; to property list. duplicate keys remain
(json-parse-string xjson :object-type 'plist)
;; (:a 3 :b 4 :b 5)

Example. Specify Array Type

(json-parse-string "[1,2,3]")
;; [1 2 3]

;; to vector
(json-parse-string "[1,2,3]" :array-type 'array)
;; [1 2 3]

;; to list
(json-parse-string "[1,2,3]" :array-type 'list)
;; (1 2 3)

Example. Special JSON values, true, false, null

;; by default,
;; json true become t
;; json false become :false
;; json null become :null
(json-parse-string "[true, false, null]")
;; [t :false :null]

;; specify how json false and null are converted
(json-parse-string "[true, false, null]" :false-object "f" :null-object 0)
;; [t "f" 0]

Import a JSON File

json-parse-buffer

(json-parse-buffer &rest ARGS)

Read JSON string from current buffer at that buffer's current cursor position.

Rest args same as json-parse-string

;; import a json file

(setq my-input-filepath "~/xx.json")

;; sample file content is ["a","🌞"]

(setq my-imported-obj
      (with-temp-buffer
        (insert-file-contents my-input-filepath)
        (goto-char (point-min))
        (json-parse-buffer)))

my-imported-obj
;; ["a" "🌞"]

Export Lisp Object to JSON as String

json-serialize

(json-serialize OBJECT &rest ARGS)

Convert lisp object to JSON string.

The string returned is emacs unibyte string. It works fine if you save it to file as Unicode: UTF-8 Encoding. If you want the string to be UTF-8, use (decode-coding-string RESULT 'utf-8)

OBJECT is translated as follows:

  • t → JSON true.
  • nil → JSON empty object.
  • number → a JSON number.
  • string → a JSON string.
  • Vector → a JSON array.
  • Hash Table → a JSON object. 🛑 WARNING: Keys must be strings.
  • Association List → a JSON object. 🛑 WARNING: Keys must be symbols.
  • Property List → a JSON object. 🛑 WARNING: Keys must be symbols. A leading colon in plist key names are elided.

💡 TIP: to export list to JSON array, you need to first turn it into vector, using vconcat. Elisp: Sequence. Join, Convert

For duplicate object keys, the first value is used.

The Lisp equivalents to the JSON null and false values are configurable in the arguments ARGS, a list of keyword/argument pairs:

  • :null-object OBJ → use OBJ to represent a JSON null value. It defaults to :null.
  • :false-object OBJ → use OBJ to represent a JSON false value. It defaults to :false.

if you specify the same value for :null-object and :false-object , the JSON output will not contain any JSON false values.

(json-serialize [1 2 3])
;; "[1,2,3]"
(json-serialize [t nil])
;; "[true,{}]"

(json-serialize nil)
;; "{}"
;; export hashtable to json
;; key must be strings
(let ((xx (make-hash-table :test 'equal)))
  (puthash "aa" 1 xx)
  (puthash "bb" 2 xx)
  (puthash "cc" 3 xx)
  (json-serialize xx))
;; "{\"aa\":1,\"bb\":2,\"cc\":3}"
;; association list
;; key must be symbols
(json-serialize (list (cons 'aa 23) (cons 'bb 24) (cons 'cc 33)) )
;; "{\"aa\":23,\"bb\":24,\"cc\":33}"
;; property list
;; key must be symbols
(json-serialize (list :aa 23 :bb 24 :cc 33) )
;; "{\"aa\":23,\"bb\":24,\"cc\":33}"
;; list cannot be exported to json
(json-serialize (list 1 2 3))
;; Debugger entered--Lisp error: (wrong-type-argument symbolp 1)

;; use vconcat to convert it to vector first
(json-serialize (vconcat (list 1 2 3)))
;; "[1,2,3]"
(json-serialize ["a" "🌞"])
"[\"a\",\"\360\237\214\236\"]"

Export Lisp Object to JSON as File

json-insert

(json-insert OBJECT &rest ARGS)

convert OBJECT to json string, and insert at current position in buffer.

rest args same as json-serialize

(setq my-lisp-obj ["a" "🌞"])
(setq my-output-filepath "~/xx.json")

(with-temp-file my-output-filepath (json-insert my-lisp-obj))

json.el (old)

library json.el is from Emacs 23 (date 2009-07) .

some of its functions are

(json-encode [1 2 3])
;; "[1,2,3]"

;; association list. symbol keys
(json-encode (list (cons 'aa 23) (cons 'bb 24) (cons 'cc 33)) )
;; "{\"aa\":23,\"bb\":24,\"cc\":33}"

;; association list. string keys
(json-encode (list (cons "aa" 23) (cons "bb" 24) (cons "cc" 33)) )
;; "{\"aa\":23,\"bb\":24,\"cc\":33}"

;; property list. symbol keys
(json-encode (list :aa 23 :bb 24 :cc 33))
;; "{\"aa\":23,\"bb\":24,\"cc\":33}"

;; property list. string keys
(json-encode (list "aa" 23 "bb" 24 "cc" 33))
;; "[\"aa\",23,\"bb\",24,\"cc\",33]"

it still have some useful functions such as

History

the functions

Reference

Elisp, Data Structure

JSON