简体   繁体   中英

Unusual syntax JSON parse problem String (Clojure)

I have a long clojure String (java.lang.String) representing a JSON. It has "normal" looking syntax like so:

"{ a:1, b:"hello" }"

The keys do not have quotes around them.

All the libraries I have looked at such as clojure.data.json want this syntax in order to parse into an object:

"{\"a\":1,\"b\":"hello"}"

Is there a way to parse the top syntax into json or clj objects? Any help is appreciated. Thank you.

Depending on your level of desperation, the Groovy JSON Slurper can read this "JSON" in the LAX setting (which allows those attributes, comments, ...)

Add the following dep:

[org.codehaus.groovy/groovy-json "2.5.6"]

Then you can run:

user=> (import [groovy.json JsonSlurper JsonParserType])
groovy.json.JsonParserType
user=> (def parser (doto (JsonSlurper.) (.setType JsonParserType/LAX)))
#'user/parser
user=> (def data (.parseText parser "{ a:1, b:\"hello\" }"))
#'user/data
user=> data
{"a" 1, "b" "hello"}

Update 2019-3-21

The link from @jas includes a comment that "it looks like YAML" (if the colons are followed by a space).

I have integrated the new snakeyaml-engine library into the Tupelo Library . API docs are here . The answer is now super-simple:

(ns tst.demo.core
  (:use demo.core tupelo.core tupelo.test)
  (:require [tupelo.parse.yaml :as yaml] ))

(dotest
  (let [data-1 "{ a: 1, b: 'Hello World' }"]
    (is= (yaml/parse data-1) {:a 1, :b "Hello World"})))

Old Answer

Given project.clj

 [io.forward/yaml "1.0.9"]

this works:

(ns tst.demo.core
  (:require [yaml.core :as yaml]) )

(def data-1 "{ a: 1, b: \"Hello World\" }" )

  (let [result-raw (yaml/parse-string data-1)
        result     (into {} result-raw)]

with result

----------------------------------
   Clojure 1.10.0    Java 10.0.1
----------------------------------

Testing tst.demo.core
result-raw   => #ordered/map ([:a 1] [:b "Hello World"])
result       => {:a 1, :b "Hello World"}

Unfortunately it (currently) fails under Java 11 because a dependent library needs a type hint. You can work around this by fixing up your project.clj :

  :dependencies [
     [io.forward/yaml "1.0.9" :exclusions [org.flatland/ordered
                                           org.yaml/snakeyaml] ]
     [org.yaml/snakeyaml "1.23"]
     [org.flatland/ordered "1.5.7"]
     [org.clojure/clojure "1.10.0"]

I filed an issue with the io.forward/yaml project to update their dependencies.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM