我认为这是一个简单的问题,但作为Clojure的初学者,我想将一个简单的JSON转换为Clojure中的EDN。
我的JSON:
{
"Data": [
{
"Metadata": {
"Series": "1/2"
},
"Hybrid": {
"Foo": 76308,
"Bar": "76308",
"Cat": "Foo123"
}
}
],
"Footer": {
"Count": 3,
"Age": 0
}
}因此,如果我们假设data是上面提到的json,那么我已经尝试使用Cheshire将其转换为EDN,如下所示:
(log/info "data" (cheshire.core/parse-string {(data) true}))但是,每当我运行这段代码时,我都会收到错误消息:
ERROR compojure.api.exception - clojure.lang.PersistentArrayMap cannot be cast to java.lang.String我想这是因为我的JSON不是字符串,但不确定是否首先需要将它转换为字符串,然后然后转换为EDN -或者是否有一种方法可以直接从JSON转换到EDN?
谢谢你提前提供帮助
发布于 2020-07-16 10:40:47
您将得到这一行的错误:
(cheshire.core/parse-string {(data) true})这里发生了什么:
无论您的数据是什么,
(data)就已经失败了。使用("{}")会给您一个class java.lang.String cannot be cast to class clojure.lang.IFn错误。而且,data不太可能是反序列化的映射,因为映射是函数,但至少有一个。因此,我们必须假设,({? true}).true,这个映射被传递给柴郡的parse-string,但是这显然不是字符串,而是一个映射,因此出现了错误。考虑到所有这些,并假设(data)返回一个String,您最好的选择是:
(cheshire.core/parse-string (data))如果你真的想要EDN的话,那就是:
(pr-str (cheshire.core/parse-string (data)))发布于 2020-07-16 06:46:43
这将有助于澄清正在发生的事情。我们首先包括一个有用的图书馆:
(ns tst.demo.core
(:use tupelo.core tupelo.test)
(:require
[tupelo.core :as t]
[tupelo.string :as str]
))为了避免文字字符串和字符串内嵌双引号的模糊性,我们使用单引号编写源JSON,然后使用助手函数str/quotes->double将字符串中的每个单引号转换为双引号。否则,我们可以从文件中读取源JSON (而不是内联的)。
(def json-str
(str/quotes->double
"{
'Data': [
{
'Metadata': {
'Series': '1/2'
},
'Hybrid': {
'Foo': 76308,
'Bar': '76308',
'Cat': 'Foo123'
}
}
],
'Footer': {
'Count': 3,
'Age': 0
}
} "))我们首先将json 字符串转换为EDN 数据结构(而不是字符串)。然后将EDN数据结构转换为EDN字符串。输出( println和prn)说明了不同之处:
(dotest
(let [edn-data (t/json->edn json-str) ; JSON string => EDN data
edn-str (pr-str edn-data) ; EDN data => EDN string
]
(newline)
(println "edn-data =>")
(spy-pretty edn-data) ; uses 'prn'
(newline)
(println "edn-str (println) =>")
(println edn-str)
(newline)
(println "edn-str (prn) =>")
(prn edn-str)))其结果是:
------------------------------------------
Clojure 1.10.2-alpha1 Java 14.0.1
------------------------------------------
Testing tst.demo.core
edn-data =>
{:Data
[{:Metadata {:Series "1/2"},
:Hybrid {:Foo 76308, :Bar "76308", :Cat "Foo123"}}],
:Footer {:Count 3, :Age 0}}
edn-str (println) =>
{:Data [{:Metadata {:Series "1/2"}, :Hybrid {:Foo 76308, :Bar "76308", :Cat "Foo123"}}], :Footer {:Count 3, :Age 0}}
edn-str (prn) =>
"{:Data [{:Metadata {:Series \"1/2\"}, :Hybrid {:Foo 76308, :Bar \"76308\", :Cat \"Foo123\"}}], :Footer {:Count 3, :Age 0}}"仔细考虑什么是数据结构,什么是字符串。如果我们在Clojure源文件中编写[1 :b "hi"],Clojure将创建一个数据结构,该数据结构是一个包含int、关键字和字符串的3元素向量。如果使用str将其转换为字符串,则输出仅为11个字符的字符串,而不是数据结构。
但是,如果我们想将这个字符串(双引号内部)粘贴到源文件中,我们不仅需要外部双引号来标记字符串的开始和结束,而且字符串中的每个双引号(例如,作为"hi"的一部分)都需要转义,这样Clojure就可以知道它们属于字符串的内部,而不标记字符串的开始或结束。
这需要一段时间来适应所有不同的模式!
Clojure Reader与Compiler
Clojure源代码文件在两次传递中得到处理。
发布于 2020-07-16 13:21:51
您获得此错误的原因是,您将变量数据作为clojure Map传递,而不是作为字符串(或json对象)传递。
这个错误也是这么说的。
核/解析-字符串需要一个json对象,它将是一个字符串。
'{ "name": "Cheshire", "needs": "a string"}'https://stackoverflow.com/questions/62928772
复制相似问题