首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在Clojure中将JSON转换为EDN?

如何在Clojure中将JSON转换为EDN?
EN

Stack Overflow用户
提问于 2020-07-16 06:28:13
回答 3查看 2.9K关注 0票数 2

我认为这是一个简单的问题,但作为Clojure的初学者,我想将一个简单的JSON转换为Clojure中的EDN。

我的JSON:

代码语言:javascript
复制
{
    "Data": [
        {
            "Metadata": {
                "Series": "1/2"
            },
            "Hybrid": {
                "Foo": 76308,
                "Bar": "76308",
                "Cat": "Foo123"
            }
        }
    ],
    "Footer": {
        "Count": 3,
        "Age": 0
    }
}

因此,如果我们假设data是上面提到的json,那么我已经尝试使用Cheshire将其转换为EDN,如下所示:

代码语言:javascript
复制
(log/info "data" (cheshire.core/parse-string {(data) true}))

但是,每当我运行这段代码时,我都会收到错误消息:

代码语言:javascript
复制
ERROR compojure.api.exception - clojure.lang.PersistentArrayMap cannot be cast to java.lang.String

我想这是因为我的JSON不是字符串,但不确定是否首先需要将它转换为字符串,然后然后转换为EDN -或者是否有一种方法可以直接从JSON转换到EDN?

谢谢你提前提供帮助

EN

回答 3

Stack Overflow用户

发布于 2020-07-16 10:40:47

您将得到这一行的错误:

代码语言:javascript
复制
(cheshire.core/parse-string {(data) true})

这里发生了什么:

无论您的数据是什么,

  1. 似乎都是可调用的--否则(data)就已经失败了。使用("{}")会给您一个class java.lang.String cannot be cast to class clojure.lang.IFn错误。而且,data不太可能是反序列化的映射,因为映射是函数,但至少有一个。因此,我们必须假设,({? true}).
  2. Then实际上是一个函数,并返回任何函数。
  3. 接下来这个调用的结果被放入一个新的映射中,作为键和值true,这个映射被传递给柴郡的parse-string,但是这显然不是字符串,而是一个映射,因此出现了错误。

考虑到所有这些,并假设(data)返回一个String,您最好的选择是:

代码语言:javascript
复制
(cheshire.core/parse-string (data))

如果你真的想要EDN的话,那就是:

代码语言:javascript
复制
(pr-str (cheshire.core/parse-string (data)))
票数 3
EN

Stack Overflow用户

发布于 2020-07-16 06:46:43

这将有助于澄清正在发生的事情。我们首先包括一个有用的图书馆:

代码语言:javascript
复制
(ns tst.demo.core
  (:use tupelo.core tupelo.test)
  (:require
    [tupelo.core :as t]
    [tupelo.string :as str]
    ))

为了避免文字字符串和字符串内嵌双引号的模糊性,我们使用单引号编写源JSON,然后使用助手函数str/quotes->double将字符串中的每个单引号转换为双引号。否则,我们可以从文件中读取源JSON (而不是内联的)。

代码语言:javascript
复制
(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字符串。输出( printlnprn)说明了不同之处:

代码语言:javascript
复制
(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)))

其结果是:

代码语言:javascript
复制
------------------------------------------
   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源代码文件在两次传递中得到处理。

  1. 选择每个源文件的文本(由多行组成的巨大字符串),并将其转换为数据结构。

  1. Clojure编译器从(1)中获取数据结构,并输出Java字节码.
票数 0
EN

Stack Overflow用户

发布于 2020-07-16 13:21:51

您获得此错误的原因是,您将变量数据作为clojure Map传递,而不是作为字符串(或json对象)传递。

这个错误也是这么说的。

核/解析-字符串需要一个json对象,它将是一个字符串。

代码语言:javascript
复制
'{ "name": "Cheshire", "needs": "a string"}'
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62928772

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档