JSON: Difference between revisions
m →{{header|Tcl}}: use better template |
|||
Line 45: | Line 45: | ||
; Pretty-print the Clojure representation of JSON. We've come full circle. |
; Pretty-print the Clojure representation of JSON. We've come full circle. |
||
(pprint-json json-map)</lang> |
(pprint-json json-map)</lang> |
||
=={{header|Factor}}== |
|||
<lang Factor> |
|||
USING: json.writer json.reader ; |
|||
SYMBOL: foo |
|||
! Load a JSON string into a data structure |
|||
"[[\"foo\",1],[\"bar\",[10,\"apples\"]]]" json> foo set |
|||
! Create a new data structure and serialize into JSON |
|||
{ { "blue" { "ocean" "water" } } >json |
|||
</lang> |
|||
=={{header|Go}}== |
=={{header|Go}}== |
Revision as of 12:44, 3 December 2010
![Task](http://static.miraheze.org/rosettacodewiki/thumb/b/ba/Rcode-button-task-crushed.png/64px-Rcode-button-task-crushed.png)
You are encouraged to solve this task according to the task description, using any language you may know.
Load a JSON string into a data structure. Also create a new data structure and serialize it into JSON. Use objects and arrays (as appropriate for your language) and make sure your JSON is valid (http://www.jsonlint.com/).
C#
This uses the JavaScriptSerializer class which was shipped with .NET 3.5.
<lang csharp>using System; using System.Collections.Generic; using System.Web.Script.Serialization;
class Program {
static void Main() { var people = new Dictionary<string, object> {{"1", "John"}, {"2", "Susan"}}; var serializer = new JavaScriptSerializer(); var json = serializer.Serialize(people); Console.WriteLine(json);
var deserialized = serializer.Deserialize<Dictionary<string, object>>(json); Console.WriteLine(deserialized["2"]);
var jsonObject = serializer.DeserializeObject(@"{ ""foo"": 1, ""bar"": [10, ""apples""] }"); var data = jsonObject as Dictionary<string, object>; var array = data["bar"] as object[]; Console.WriteLine(array[1]); }
}</lang>
Clojure
<lang clojure>(ns json.example
(:use [clojure.contrib.json]))
; Load as Clojure data structures and bind the resulting structure to 'json-map'.
(def json-map (read-json "{ \"foo\": 1, \"bar\": [10, \"apples\"] }"))
- Use pr-str to print out the Clojure representation of the JSON created by read-json.
(pr-str json-map)
- Pretty-print the Clojure representation of JSON. We've come full circle.
(pprint-json json-map)</lang>
Factor
<lang Factor> USING: json.writer json.reader ;
SYMBOL: foo
! Load a JSON string into a data structure "[[\"foo\",1],[\"bar\",[10,\"apples\"]]]" json> foo set
! Create a new data structure and serialize into JSON
{ { "blue" { "ocean" "water" } } >json
</lang>
Go
<lang go>package main import "json" import "fmt"
func main() {
var data map[string]interface{} json.Unmarshal([]byte("{ \"foo\": 1, \"bar\": [10, \"apples\"] }"), &data) fmt.Println(data)
sample := map[string]interface{}{ "blue": []interface{}{1,2}, "ocean": "water" } json_string, err := json.Marshal(sample) if err == nil { fmt.Println(string(json_string)) } else { fmt.Println(err) }
}</lang>
J
Here is a minimal implementation based on an old email message.
<lang j>NB. character classes: NB. 0: whitespace NB. 1: " NB. 2: \ NB. 3: [ ] , { } : NB. 4: ordinary classes=.3<. '"\[],{}:' (#@[ |&>: i.) a. classes=.0 (I.a.e.' ',CRLF,TAB)} (]+4*0=])classes
words=:(0;(0 10#:10*".;._2]0 :0);classes)&;: NB. states:
0.0 1.1 2.1 3.1 4.1 NB. 0 whitespace 1.0 5.0 6.0 1.0 1.0 NB. 1 " 4.0 4.0 4.0 4.0 4.0 NB. 2 \ 0.3 1.2 2.2 3.2 4.2 NB. 3 { : , } [ ] 0.3 1.2 2.0 3.2 4.0 NB. 4 ordinary 0.3 1.2 2.2 3.2 4.2 NB. 5 "" 1.0 1.0 1.0 1.0 1.0 NB. 6 "\
)
tokens=. ;:'[ ] , { } :' actions=: lBra`rBracket`comma`lBra`rBracket`colon`value
NB. action verbs argument conventions: NB. x -- boxed json word NB. y -- boxed json state stack NB. result -- new boxed json state stack NB. NB. json state stack is an list of boxes of incomplete lists NB. (a single box for complete, syntactically valid json) jsonParse=: 0 {:: (,a:) ,&.> [: actions@.(tokens&i.@[)/ [:|.a:,words
lBra=: a: ,~ ] rBracket=: _2&}.@], [:< _2&{::@], _1&{@] comma=: ] rBrace=: _2&}.@], [:< _2&{::@], [:|: (2,~ [: -:@$ _1&{@]) $ _1&{@] colon=: ] value=: _1&}.@], [:< _1&{::@], jsonValue&.>@[
NB. hypothetically, jsonValue should strip double quotes NB. interpret back slashes NB. and recognize numbers jsonValue=:]
require'strings'
jsonSer1=: ']' ,~ '[' }:@;@; (',' ,~ jsonSerialize)&.>
jsonSer0=: '"', jsonEsc@:":, '"'"_
jsonEsc=: rplc&(<;._1' \ \\ " \"')
jsonSerialize=:jsonSer0`jsonSer1@.(*@L.)</lang>
Example use:
<lang> jsonParse'{ "blue": [1,2], "ocean": "water" }' ┌──────────────────────────────┐ │┌──────┬─────┬───────┬───────┐│ ││"blue"│┌─┬─┐│"ocean"│"water"││ ││ ││1│2││ │ ││ ││ │└─┴─┘│ │ ││ │└──────┴─────┴───────┴───────┘│ └──────────────────────────────┘
jsonSerialize jsonParse'{ "blue": [1,2], "ocean": "water" }'
[["\"blue\"",["1","2"],"\"ocean\"","\"water\""]]</lang>
Note that these are not strict inverses of each other. These routines allow data to be extracted from json and packed into json format, but only in a minimalistic sense. No attempts are made to preserve the subtleties of type and structure which json can carry. This should be good enough for most applications which are required to deal with json but will not be adequate for ill behaved applications which exploit the typing mechanism to carry significant information.
Also, a different serializer will probably be necessary, if you are delivering json to legacy javascript. Nevertheless, these simplifications are probably appropriate for practical cases.
JavaScript
Requires JSON library, now present in some browsers. <lang JavaScript>var data = JSON.parse('{ "foo": 1, "bar": [10, "apples"] }');
var sample = { "blue": [1,2], "ocean": "water" }; var json_string = JSON.stringify(sample);</lang>
Of course, it IS called JavaScript Object Notation, so it is a JavaScript object literal, and you can, alternately, parse it by just eval'ing it. This should work in any browser without a library. (Eval may be dangerous, depending on the source of the data.) However, there is an ambiguity with parsing JavaScript object literals by themselves, where it might be mistakenly interpreted as a block, and the key followed by a colon as a label. To avoid this, remember to surround it in parentheses to force it to be interpreted as an expression: <lang javascript>var data = eval('(' + '{ "foo": 1, "bar": [10, "apples"] }' + ')');</lang>
OCaml
compile with:
ocamlfind opt -o j.opt j.ml -linkpkg -package json-static -syntax camlp4o
<lang ocaml>type json item =
< name "Name": string; kingdom "Kingdom": string; phylum "Phylum": string; class_ "Class": string; order "Order": string; family "Family": string; tribe "Tribe": string >
let str = "
{ \"Name\": \"camel\", \"Kingdom\": \"Animalia\", \"Phylum\": \"Chordata\", \"Class\": \"Mammalia\", \"Order\": \"Artiodactyla\", \"Family\": \"Camelidae\", \"Tribe\": \"Camelini\" }"
let () =
let j = Json_io.json_of_string str in print_endline (Json_io.string_of_json j);</lang>
Oz
With the JSON library from here: <lang oz>declare
[JSON] = {Module.link ['JSON.ozf']}
{System.show {JSON.decode "{ \"foo\": 1, \"bar\": [10, \"apples\"] }"}}
Sample = object(blue:array(1 2) ocean:"water") {System.showInfo {JSON.encode Sample}}</lang>
Output:
object(bar:array(10 [97 112 112 108 101 115]) foo:1) {"blue":[1,2],"ocean":"water"}
Perl
<lang perl>use JSON;
my $data = decode_json('{ "foo": 1, "bar": [10, "apples"] }');
my $sample = { blue => [1,2], ocean => "water" }; my $json_string = encode_json($sample);</lang>
Perl 6
Using [1]
<lang perl> use JSON::Tiny;
my $data = from-json('{ "foo": 1, "bar": [10, "apples"] }');
my $sample = { blue => [1,2], ocean => "water" }; my $json_string = to-json($sample); </lang>
PHP
<lang php><?php $data = json_decode('{ "foo": 1, "bar": [10, "apples"] }'); // dictionaries will be returned as objects $data2 = json_decode('{ "foo": 1, "bar": [10, "apples"] }', true); // dictionaries will be returned as arrays
$sample = array( "blue" => array(1,2), "ocean" => "water" ); $json_string = json_encode($sample); ?></lang>
PicoLisp
PicoLisp has no JSON library, but it is easy enough to write one: <lang PicoLisp>(de checkJson (X Item)
(unless (= X Item) (quit "Bad JSON" Item) ) )
(de readJson ()
(case (read "_") ("{" (make (for (X (readJson) T (readJson)) (checkJson ":" (readJson)) (link (cons X (readJson))) (T (= "}" (setq X (readJson)))) (checkJson "," X) ) ) ) ("[" (make (link T) # Array marker (for (X (readJson) T (readJson)) (link X) (T (= "]" (setq X (readJson)))) (checkJson "," X) ) ) ) (T @) ) )
(de printJson (Item) # For simplicity, without indentation
(cond ((atom Item) (print Item)) ((=T (car Item)) (prin "[") (map '((X) (printJson (car X)) (and (cdr X) (prin ", ")) ) (cdr Item) ) (prin "]") ) (T (prin "{") (map '((X) (print (caar X)) (prin ": ") (printJson (cdar X)) (and (cdr X) (prin ", ")) ) Item ) (prin "}") ) ) )</lang>
This reads/prints JSON from/to files, pipes, sockets etc. To read from a string, a pipe can be used:
: (pipe (prinl "{ \"foo\": 1, \"bar\": [10, \"apples\"] }") (readJson) ) -> (("foo" . 1) ("bar" T 10 "apples")) : (printJson (quote ("name" . "Smith") ("age" . 25) ("address" ("street" . "21 2nd Street") ("city" . "New York") ("state" . "NY") ("zip" . "10021") ) ("phone" T "212 555-1234" "646 555-4567") ) ) {"name": "Smith", "age": 25, ... {"street": ... "phone": ["212 555-1234", ...
Python
<lang Python>>>> import json >>> data = json.loads('{ "foo": 1, "bar": [10, "apples"] }') >>> sample = { "blue": [1,2], "ocean": "water" } >>> json_string = json.dumps(sample) >>> json_string '{"blue": [1, 2], "ocean": "water"}' >>> sample {'blue': [1, 2], 'ocean': 'water'} >>> data {'foo': 1, 'bar': [10, 'apples']}</lang>
Because most of JSON is valid Python syntax (except "true", "false", and "null", and a few obscure escape sequences), it is also possible (but not recommended) to parse JSON using eval(): <lang python>>>> true = True; false = False; null = None >>> data = eval('{ "foo": 1, "bar": [10, "apples"] }') >>> data {'foo': 1, 'bar': [10, 'apples']}</lang>
REBOL
Using json.org/json.r
<lang rebol>json-str: {{"menu": {
"id": "file", "string": "File:", "number": -3, "boolean": true, "boolean2": false, "null": null, "array": [1, 0.13, null, true, false, "\t\r\n"], "empty-string": "" }
}}
res: json-to-rebol json-str js: rebol-to-json res </lang>
json-to-rebol Result:
make object! [ menu: make object! [ id: "file" string: "File:" number: -3 boolean: true boolean2: false null: none array: [1 0.13 none true false "^-^M^/"] empty-string: "" ] ]
rebol-to-json Result:
{ "menu": { "id": "file", "string": "File:", "number": -3, "boolean": true, "boolean2": false, "null": null, "array": [1, 0.13, null, true, false, "\t\r\n"], "empty-string": "" } }
Ruby
Uses
package json
<lang ruby>require 'json' ruby_obj = JSON.parse('{"blue": [1, 2], "ocean": "water"}') puts ruby_obj.inspect puts ruby_obj.class puts ruby_obj["blue"].class ruby_obj["ocean"] = {"water" => %w{fishy salty}} puts JSON.generate(ruby_obj)</lang>
Outputs
{"blue"=>[1, 2], "ocean"=>"water"} Hash Array {"blue":[1,2],"ocean":{"water":["fishy","salty"]}}
Tcl
For parsing JSON,
provides the capability (see the Tcler's Wiki page on it for more discussion):
<lang tcl>package require json set sample {{ "foo": 1, "bar": [10, "apples"] }}
set parsed [json::json2dict $sample] puts $parsed</lang> Output:
foo 1 bar {10 apples}
However, that package is very weak in its generation of JSON because Tcl's official type system is substantially different to that envisaged by JSON. It's possible to work around this though the use of Tcl 8.6, as this next example shows:
<lang tcl>package require Tcl 8.6
proc tcl2json value {
# Guess the type of the value; deep *UNSUPPORTED* magic! regexp {^value is a (.*?) with a refcount} \
[::tcl::unsupported::representation $value] -> type
switch $type {
string { # Skip to the mapping code at the bottom } dict { set result "{" set pfx "" dict for {k v} $value { append result $pfx [tcl2json $k] ": " [tcl2json $v] set pfx ", " } return [append result "}"] } list { set result "\[" set pfx "" foreach v $value { append result $pfx [tcl2json $v] set pfx ", " } return [append result "\]"] } int - double { return [expr {$value}] } booleanString { return [expr {$value ? "true" : "false"}] } default { # Some other type; do some guessing... if {$value eq "null"} { # Tcl has *no* null value at all; empty strings are semantically # different and absent variables aren't values. So cheat! return $value } elseif {[string is integer -strict $value]} { return [expr {$value}] } elseif {[string is double -strict $value]} { return [expr {$value}] } elseif {[string is boolean -strict $value]} { return [expr {$value ? "true" : "false"}] } }
}
# For simplicity, all "bad" characters are mapped to \u... substitutions set mapped [subst -novariables [regsub -all {[][\u0000-\u001f\\""]} \
$value {[format "\\\\u%04x" [scan {& } %c]]}]]
return "\"$mapped\""
}</lang>
Sample code (note that the value is built with dict create
and list
so that there is some auxiliary type hints available, which the above procedure can read):
<lang tcl>set d [dict create blue [list 1 2] ocean water]
puts [tcl2json $d]</lang>
Output:
{"blue": [1, 2], "ocean": "water"}
Note that this is capable of correctly handling the round-trip of values parsed from the json
package described above.