JSON: Difference between revisions

2,473 bytes added ,  13 years ago
→‎Tcl: Added implementation
(Added note that datamodel in programming language should be appropriate)
(→‎Tcl: Added implementation)
Line 127:
sample = { "blue": [1,2], "ocean": "water" }
json_string = json.dumps(sample)</lang>
 
=={{header|Tcl}}==
For parsing JSON, there is a package in {{libheader|Tcllib}} which provides the capability:
<lang tcl>package require json
set sample {{ "foo": 1, "bar": [10, "apples"] }}
 
set parsed [json::json2dict $sample]
puts $parsed</lang>
Output:
<pre>foo 1 bar {10 apples}</pre>
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 <code>dict create</code> and <code>list</code> 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:
<pre>{"blue": [1, 2], "ocean": "water"}</pre>
Note that this is capable of correctly handling the round-trip of values parsed from the <code>json</code> package described above.
 
[[Category:Data Structures]]
Anonymous user