I think this is a simple question but as a beginner in Clojure, I would like to convert a simple JSON to EDN in Clojure.
My JSON:
{
"Data": [
{
"Metadata": {
"Series": "1/2"
},
"Hybrid": {
"Foo": 76308,
"Bar": "76308",
"Cat": "Foo123"
}
}
],
"Footer": {
"Count": 3,
"Age": 0
}
}
So if we assume that data is the json above, I have tried to convert it to an EDN using Cheshire like so:
(log/info "data" (cheshire.core/parse-string {(data) true}))
However, whenever I run this bit of code, I get the error message:
ERROR compojure.api.exception - clojure.lang.PersistentArrayMap cannot be cast to java.lang.String
I think I am getting this because my JSON is not a string, but unsure if I first need to convert it to a string, and then converting to EDN - or if there is a way I can go straight from JSON to EDN?
Thank you for your help in advance
This will help to clarify what is occurring. We start off by including a helpful library:
In order to avoid the ambiguity of double-quotes for both a literal string and embedded inside of the string, we write the source JSON using single quotes, then use a helper function
str/quotes->double
to convert every single-quote in the string into a double-quote. Otherwise, we could have read in the source JSON from a file (instead of having it inline).We first convert the json string into an EDN data structure (not a string). We then convert the EDN data struction into an EDN string. The output (both
println
andprn
) illustrate the differences:with result:
Think carefully about what is a data structure and what is a string. If we write
[1 :b "hi"]
in a Clojure source file, the Clojure Reader creates a data structure that is a 3-element vector containg an int, a keyword, and a string. If we convert that into a string usingstr
, the output is just a string of 11 characters and is not a data structure.However, if we want to paste that string (inside of double-quotes) into our source file, we need not only the outer double-quotes to mark the beginning and end of the string, but each double-quote inside the string (e.g. as part of the
"hi"
) needs to be escaped, so the Clojure Reader can tell that they belong inside of the string and don't mark the beginning or end of a string.It takes a while to get used to all of the different modes!
Clojure Reader vs Compiler
Clojure source code files are processed in 2 passes.
The Clojure Reader takes the text of each source file (a giant string of many lines) and converts it into a data structure.
The Clojure Compiler takes the data structure from (1) and outputs Java bytecode.