Hi All,
Sorry if this has been covered, I am a bit late to the party on the mailing list here... anyway: is there a conventional way to achieve round-tripping of e.g. plists with cl-json? For example:
CL-USER> (setq obj (list :|iid| NIL :|bashee| (list :|%rp%| NIL))) (:|iid| NIL :|bashee| (:|%rp%| NIL)) CL-USER> (json:encode-json-to-string obj) "["iid",null,"bashee",["%rp%",null]]" CL-USER> (json:decode-json-from-string (json:encode-json-to-string obj)) ("iid" NIL "bashee" ("%rp%" NIL))
At the end here, what I really want is the identical plist back:
(:|iid| NIL :|bashee| (:|%rp%| NIL))
The CL-JSON documentation is clear that symbols in Lisp go to strings in JSON, which come back as strings in Lisp --- but is there any general, conventional technique people are using on top of this to preserve printable Lisp objects (mainly I'm talking about symbols here) through round-trips Lisp->JSON->Lisp?
Up until now we have been using base64 encoding for this kind of thing:
(base64-encode (format nil "~s" obj))
to get the Lisp stuff into a format for the web page which can be passed through e.g. as the parameter for an Ajax call, then
(read-from-string (base64-decode ...))
back in Lisp to get it back and usable in Lisp. Putting everything into a base64 encoded string avoids problems with having to escape characters or other weirdness caused by strange characters which can confuse JavaScript. But this gets to be kind of cryptic (it makes the web page source code pretty much unreadable for humans), and I am learning that it starts failing for UTF-8 characters, etc, unless we are very careful about our base64 encoding. So I am hoping to standardize on JSON for this kind of thing, if there is a generally accepted way to do round-tripping.
Plus I want to use json for scraping specific form-control values from a web page through Ajax (right now we have god-awful Javascript with all kinds of crazy character-escaping workarounds to do this). But I think that is another topic...
Anyway am I barking up the wrong tree here trying to get round-tripping with cl-json?
Regards,
Dave
As far as I can tell, there's no way for CL-JSON to know whether something was intended to be a string or a symbol (and, if a symbol, what package). I can think of two possible solutions:
1. if it's specifically plist keys you are interested in, somehow mark or know when an array is a plist. Then simply decode all the keys as symbols (in the keyword package?) and all the values as normal.
2. More elaborate: set up a special kind of JSON object that will capture the information about symbols, as appropriate. E.g.,:
{ type: "lispSymbol", package: "pkg-name", name: "symbolName" }
and decode that as
'pkg-name:|symbolName|
That's probably the most robust way to do this.
cheers, r