Emacs24 comes standard with a JSON library called json.el
.This only provides encoders and decoders, and how to handle the converted S formula varies from user to user.
Functions such as car/cdr/assoc/elt
are provided to reference elements of the S expression.However, if you use them a lot, it seems difficult to see where you are referring.
; What's in FILE.json?
;; {
;; "foo": {
;; "bar": [1, 2, 3]
;; }
;; }
(require'json)
(let*((json-key-type'string)
(json(json-read-file "FILE.json"))
;; json->((("foo"("bar".[123])))
(elt(cdr(assoc "bar"(cdr(assoc "foo"json))))0)
<=>1
So, is there an easy way (or library) to access the nested S expression like (json "foo" "bar" 0)
?If it is a library, it would be even better if the package is distributed by MELPA etc.
The question is for Elisp, but if you know how other LISP languages handle JSON and XML converted to S expression, please let me know.
json elisp lisp
How do other LISP languages handle JSON and XML converted to S expressions?
Saito Atsushi is porting jsonpath to Gauche.
http://saito.hatenablog.jp/entry/2013/06/20/233036
However, due to the loose JSON, it does not seem to be as easy to use as XPath :
http://saito.hatenablog.jp/entry/2013/06/25/095332
As for XML, I think the portable XPath implementation SXPath is used between Schemes.
How about using the following functions?
(defun find-json-value (node json)
(let*((key(car node))
(next(cdr node))
(rest(and(listp(cdrjson))
(assoc key json)))
(if (and key next rest)
(find-json-value next rest)
(cdr rest)))
(find-json-value'("foo" "bar") json)
=>[123]
Simply explore the assoc-list, but for your information.
Regarding "How do other LISP languages handle JSON and XML converted to S expression?" 2. Only JSON.
There is also json-tools whether it is an R6RS Scheme processing system.This is the Scheme version of JSONSelect, which provides CSS selector-style JSON access and SXPath-affected APIs
.
The Key-Value library kv.el
distributed by MELPA has associative list dot access functions kvdotassoc
, kvdotassq
(dotassq
).
https://github.com/nicferrier/emacs-kv
The associative list keys can handle both the symbol foo.bar
and the string "foo.bar"
and can nest keys.However, it does not support array element access.
(let((json(json-read-file "FILE.json"))))
;; json->(((foo(bar.[123])))))
(print(dotassoc'foo json)) ;->((bar.[123]))
(print(dotassoc'foo.bar json)) ;->[123]
(print(dotassoc'abc.xyzjson)) ;->nil
)
It's like Clojure's get-in
or Ruby's dig
to go through nested structures.
If you copy Clojure's get-in
interface, it looks like this.
(require'cl-lib)
(defunget-in (dat keys)
(cl-reduce
(lambda(xk)(if(vectorpx)(eltxk)(cdr(assockx)))))
keys —initial-value dat))
(get-in json'("foo" "bar" 0))
;;=>1
(get-in json ["foo" "bar" 0])
;;=>1
I have found an ELPA package called let-alist
, so I will introduce it to you.
http://elpa.gnu.org/packages/let-alist.html
This package provides access to dotted symbols such as .KEY
instead of (cdr(assq KEY ALIST))
.You can also nest symbols.
However, as per the package name, only associative lists (and keys are symbols) are used to access the array, etc.
(require'let-alist)
(let-alist(json-read-file "FILE.json")
(print.foo);->((bar.[123]))
(print.foo.bar);->[123]
(print(elt.foo.bar0)) ;->1
)
I can't handle any JSON, so it's just for reference only.
You can also write dash and dash-functional in the following ways: It seems to be a leading macro famous for clojure.
(->>
(json-read-from-string "{\"foo\":{\"bar\":[1,2,3]}}")
(funcall (-compose'cdr (-partial'assoc'foo)))
(funcall (-compose'cdr (-partial'assoc'bar)))
(funcall (-flip'elt) 0)
)
;; =>1
© 2024 OneMinuteCode. All rights reserved.