JSON parsing using clojure - json

I'm using Clj Json library to parse JSON data in clojure. How do i access all the values itertively and print it in a text file?
I have read the JSON. Can someone help me in parsing it and writing it to a text file?
def all-records (json/read-json (slurp "file.json")));
(println all-records);
(println (get-in all-records [:entry]))
Update:
Here is a sample json file :
{"markers" : [{"point" :new GLatLng (40.266044, -74.718479),
"homeTeam" : "Lawrence Library",
"awayTeam" : "LUGip",
"markerImage" : "images/red.png",
"information" : "Linux users group meets second Wednesday of each month.",
"fixture" : "Wednesday 7pm",
"capacity" : "",
"previousScore" : ""},
{"point" :new GLatLng (40.211600, -74.695702),
"homeTeam" : "Hamilton Library",
"awayTeam" : "LUGip HW SIG",
"markerImage" : "images/white.png"]}

If you put the json in a file like so:
{"markers" : [{"point" :new GLatLng (40.266044, -74.718479),
"homeTeam" : "Lawrence Library",
"awayTeam" : "LUGip",
"markerImage" : "images/red.png",
"information" : "Linux users group meets second Wednesday of each month.",
"fixture" : "Wednesday 7pm",
"capacity" : "",
"previousScore" : ""},
{"point" :new GLatLng (40.211600, -74.695702),
"homeTeam" : "Hamilton Library",
"awayTeam" : "LUGip HW SIG",
"markerImage" : "images/white.png"]}
and then write a little code:
(ns ...
(:require [cheshire.core :as cc] ...))
(def json-data (slurp "resources/sample.json"))
(defn json->clj [arg]
"Shortcut to cheshire.core/parse-string"
(cc/parse-string arg true)) ; true => keywordize-keys
(pprint (json->clj json-data))
you get an error
Error refreshing environment: com.fasterxml.jackson.core.JsonParseException:
Unrecognized token 'new': was expecting 'null', 'true', 'false' or NaN
The problem is the 2 occurrances of new GLatLng (40.266044, -74.718479) in the JSON data. JSON data is only data, like strings & numbers. You cannot have a function call (in this case a constructor call) embedded in the JSON.

Related

How to parse json string in vb6

I'm calling a web service in VB6 which returns a json string as response. I'm able to hold the response in a string. now I want to show the each parameter separately how can I extract the values from the string ?. a sample string is here :
{
"id": "22144",
"t" : "AAPL",
"e" : "NASDAQ",
"l" : "108.00",
"l_fix" : "108.00",
"l_cur" : "108.00",
"s": "2",
"ltt":"4:00PM EDT",
"lt" : "Aug 10, 4:00PM EDT",
"lt_dts" : "2016-08-10T16:00:01Z",
"c" : "-0.81",
"c_fix" : "-0.81",
"cp" : "-0.74",
"cp_fix" : "-0.74",
"ccol" : "chr",
"pcls_fix" : "108.81",
"el": "107.98",
"el_fix": "107.98",
"el_cur": "107.98",
"elt" : "Aug 10, 5:16PM EDT",
"ec" : "-0.02",
"ec_fix" : "-0.02",
"ecp" : "-0.02",
"ecp_fix" : "-0.02",
"eccol" : "chr",
"div" : "0.57",
"yld" : "2.11"
}
I've found VB-JSON works really well for parsing json in VB6.
You can download it from here.
VB-JSON: A Visual Basic 6 (VB6) JSON Parser Class Library
The .zip file that you download will contain a sample project and the library, which is called JSON.bas.
The main parser function is JSON.parse and you pass it the json string as parameter.
So in your project, you only need to include / add the JSON.bas file.
Sample Usage (from the sample project) :
Private Sub cmdObjToJSON_Click()
Dim p As Object
Dim sInputJson As String
sInputJson = "{ width: '200', frame: false, height: 130, bodyStyle:'background-color: #ffffcc;',buttonAlign:'right', items: [{ xtype: 'form', url: '/content.asp'},{ xtype: 'form2', url: '/content2.asp'}] }"
MsgBox "Input JSON string: " & sInputJson
' sets p
Set p = JSON.parse(sInputJson)
MsgBox "Parsed object output: " & JSON.toString(p)
MsgBox "Get Bodystyle data: " & p.Item("bodyStyle")
MsgBox "Get Form Url data: " & p.Item("items").Item(1).Item("url")
p.Item("items").Item(1).Add "ExtraItem", "Extra Data Value"
MsgBox "Parsed object output with added item: " & JSON.toString(p)
End Sub
As it applies to your case. Something like the following might work (with some tweaks if needed).
Dim parsedJsonObject As Object
Set parsedJsonObject = JSON.parse(yourJsonStringVariable)
'Print the ticker ( t in your json )
Debug.Print parsedJsonObject.Item("t")
There is a JSON parser library for Visual Basic that you can find in http://json.org/.
You can either use VB-JSON or PW.JSON.

Accessing array in Json Data with Clojurescript

I am new Clojurescript and want to hack arround with clojurescript and electron based on an small json file.
I am doing something like (with transit/cljs)
(def jsondata (t/read (t/reader :json) (.readFileSync fs path_to_file "utf8")))) )
first I check if status is ok, that works fine...
(let [json_status (get jsondata "status")]
(.log js/console "JSON Glossar Status:" json_status))
now, how can I access one of the maps in the pages array, or step through the map?
{"status":"ok",
"pages":[
{
"id":1,
"name":"name1",
"image":"imagename1.png",
"children":[
{
"id":1,
"copytext":"kdjsldjsljfl"
},
{
"id":2,
"copytext":"dksdöfksöfklsöf"
}
]
},
{
"id":2,
"name":"name1",
"image":"imagename1.png",
"children":[
{
"id":4,
"copytext":"kdjsldjsljfl"
},
{
"id":5,
"copytext":"dksdöfksöfklsöf"
}
]
}
]
}
You can use aget (i.e. "array get") for nested ClojureScript / JavaScript interop.
For example, if you wanted to access the second map item in your "pages" array, you could do this:
(def my-js-object
(clj->js {:status "ok"
:pages [{:id 1
:name "foo"
:children []}
{:id 2
:name "bar"
:children []}]}))
(aget my-js-object "pages" 1)
In the above code I'm simply using clj->js to construct a notional (and incomplete) representation of your JSON; I hope this is enough to make sense.
My REPL output was:
#js {:id 2, :name "bar", :children #js []}
If you wanted to do something more complex with each page item, e.g. "map over each page hashmap and pull out the name values", then you could make use of the .- JS property accessor
(->> (.-pages my-js-object)
(map #(.-name %)))
REPL output:
("foo" "bar")
To not answer the question, you could use
js->cljs, https://cljs.github.io/api/cljs.core/js-GTclj, to turn your json into a normal Clojure data structure and use Clojures normal fns to extract the data you want.

Look for JSON example with all allowed combinations of structure in max depth 2 or 3

I've wrote a program which process JSON objects. Now I want to verify if I've missed something.
Is there an JSON-example of all allowed JSON structure combinations? Something like this:
{
"key1" : "value",
"key2" : 1,
"key3" : {"key1" : "value"},
"key4" : [
[
"string1",
"string2"
],
[
1,
2
],
...
],
"key5" : true,
"key6" : false,
"key7" : null,
...
}
As you can see at http://json.org/ on the right hand side the grammar of JSON isn't quite difficult, but I've got several exceptions because I've forgotten to handles some structure combinations which are possible. E.g. inside an array there can be "string, number, object, array, true, false, null" but my program couldn't handle arrays inside an array until I ran into an exception. So everything was fine until I got this valid JSON object with arrays inside an array.
I want to test my program with a JSON object (which I'm looking for). After this test I want to be feel certain that my program handle every possible valid JSON structure on earth without an exception.
I don't need nesting in depth 5 or so. I only need something in nested depth 2 or max 3. With all base types which nested all allowed base types, inside this base type.
Have you thought of escaped characters and objects within an object?
{
"key1" : {
"key1" : "value",
"key2" : [
"String1",
"String2"
],
},
"key2" : "\"This is a quote\"",
"key3" : "This contains an escaped slash: \\",
"key4" : "This contains accent charachters: \u00eb \u00ef",
}
Note: \u00eb and \u00ef are resp. charachters ë and ï
Choose a programming language that support json.
Try to load your json, on fail the exception's message is descriptive.
Example:
Python:
import json, sys;
json.loads(open(sys.argv[1]).read())
Generate:
import random, json, os, string
def json_null(depth = 0):
return None
def json_int(depth = 0):
return random.randint(-999, 999)
def json_float(depth = 0):
return random.uniform(-999, 999)
def json_string(depth = 0):
return ''.join(random.sample(string.printable, random.randrange(10, 40)))
def json_bool(depth = 0):
return random.randint(0, 1) == 1
def json_list(depth):
lst = []
if depth:
for i in range(random.randrange(8)):
lst.append(gen_json(random.randrange(depth)))
return lst
def json_object(depth):
obj = {}
if depth:
for i in range(random.randrange(8)):
obj[json_string()] = gen_json(random.randrange(depth))
return obj
def gen_json(depth = 8):
if depth:
return random.choice([json_list, json_object])(depth)
else:
return random.choice([json_null, json_int, json_float, json_string, json_bool])(depth)
print(json.dumps(gen_json(), indent = 2))

Why do I have to flatten nested JSON when using the ring json middleware

I have been writing a clojure application with ring and compojure. I am using the ring.middleware.json middleware for handling JSON so I don't have to serialise and deserialise it myself in my code.
This middleware only seems to correctly parse nested JSON when given in a flattened format, for example if I want to POST nested data to an API route I have to encode it as:
{"task" : 1,
"success" : false,
"files[0][type]" : "log",
"files[0][sha256]" : "adef5c",
"files[0][url]" : "s3://url"}
Instead of, what seems to me, more standard JSON:
{"task" : 1,
"success" : false,
"files" : [{"type" : "log", "sha256" : "adef5c", "url": "s3://url"}]}
Is this indented or a standard way of posting nested JSON? Here is my middleware stack:
(defn middleware [handler]
(-> handler
(wrap-json-response)
(wrap-with-logger)
(api)))
Here is a full Clojure example of post and get routes that handle JSON or return JSON:
(ns ring-app.core
(:require [ring.adapter.jetty :as jetty]
[compojure.core :as compojure]
[ring.middleware.keyword-params :refer [wrap-keyword-params]]
[ring.middleware.json :refer [wrap-json-response wrap-json-body]]
[ring.util.http-response :as response]
[clojure.pprint :refer [pprint]]
[ring.middleware.reload :refer [wrap-reload]]))
(defn json-get [request]
(response/ok
{"task" 1
"success" false
"files" [{"type" "log" "sha256" "adef5c" "url" "s3://url"}]}))
(defn json-post [request]
(let [bpdy (:body request)]
(prn bpdy)
(response/ok bpdy)))
(compojure/defroutes handler_
(compojure/GET "/get" request json-get)
(compojure/POST "/post" request json-post))
(defn wrap-nocache [handler]
(fn [request]
(-> request
handler
(assoc-in [:headers "Pragma"] "no-cache"))))
(def handler
(-> #'handler_ wrap-nocache wrap-reload wrap-json-response wrap-json-body ) )
The get endpoint returns the nested structure:
curl http://localhost:3000/get
; {"task":1,"success":false,"files":[{"type":"log","sha256":"adef5c","url":"s3://url"}]}
And the POST endpoint parses the json and create a Clojure data structure:
curl -X post -d '{"task":1,"success":false,"files":[{"type":"log","sha256":"adef5c","url":"s3://url"}]}' -H "Accept: application/json" -H "Content-type: application/json" http://localhost:3000/post
; {"task":1,"success":false,"files":[{"type":"log","sha256":"adef5c","url":"s3://url"}]}
This is roundtripping on JSON->CLJ->JSON
The json ring middleware expects the Content-type to be properly set so maybe that was why the structure was not parsed properly in your case ?

clojure loop through json data

I have a problem parsing json data in a loop. Iam a clojure beginner and need some hint for looping through json data.
The data looks like this:
{"photoset" {"primary" "8455893107", "total" "2", "pages" 1, "perpage" 500, "page" 1,
"per_page" 500, "photo"
[{"id" "8455893107", "secret" "1a3236df06", "server" "8087",
"farm" 9, "title" "IMG_0137", "isprimary" "1"}
{"id" "8469482476", "secret" "4c1bf59214",
"server" "8235", "farm" 9, "title" "HippieBus", "isprimary" "0"}]
, "owner"
"93029076#N07", "id" "72157632724688181", "ownername" "clojureB5"}, "stat" "ok"}
What I want to do is loop through the two photos and build a new url with the id and farm value like http://www.flickr.com/farm/id
I know that I can get one value like this:
(-> (get-in (cheshire.core/parse-string (:body picList)) ["photoset" "photo"]) first (get "id"))
But I can I now loop through it?
You can simply use map.
(->> (get-in data ["photoset" "photo"])
(map #(str "http://www.flickr.com/" (get % "farm") "/" (get % "id"))))
It will yield the following list:
("http://www.flickr.com/9/8455893107" "http://www.flickr.com/9/8469482476")