The Tcllib
JSON module provides a parser and a generator. The parser is in the namespace
::json, the generator is in the namespace
::json::write. Both form an "ensemble command".
Reference edit
- json
- json::write
Parse JSON edit
json2prettydict Patch
ABU 2012-04-18:
Few weeks ago I posted a patch-proposal [
1] for the json package.
I added a new proc named
json2prettydict. Aim of this proc is to return a "pretty-printed" tcl-dictionary
I think this proc could be useful for documenting complex nested dictionaries.Here is an example:
set jsonStr { \
{ "photos": { "page": 1, "pages": "726", "perpage": 3, "total": "7257",
"photo": [
{ "id": "6974156079", "owner": "74957296@N08", "secret": "005d743f82", "server": "7197", "farm": 8, "title": "Kenya Watamu \"Deep Sea Fishing\" \"Indian Ocean\" \"Blue Marlin\"", "ispublic": 1, "isfriend": 0, "isfamily": 0 },
{ "id": "6822988100", "owner": "52857411@N08", "secret": "56630c18e8", "server": "7183", "farm": 8, "title": "Gedi Ruins, Local Guide", "ispublic": 1, "isfriend": 0, "isfamily": 0 },
{ "id": "6822909640", "owner": "52857411@N08", "secret": "f4e392ea36", "server": "7063", "farm": 8, "title": "Local Fisherman, Mida Creek", "ispublic": 1, "isfriend": 0, "isfamily": 0 }
] }, "stat": "ok" }
}
First, just for comparision, call
json2dictset d1 [json::json2dict $jsonStr]
result is the following
photos {page 1 pages 726 perpage 3 total 7257 photo {{id 6974156079 owner 74957296@N08 secret 005d743f82 server 7197 farm 8 title {Kenya Watamu "Deep Sea Fishing" "Indian Ocean" "Blue Marlin"} ispublic 1 isfriend 0 isfamily 0} {id 6822988100 owner 52857411@N08 secret 56630c18e8 server 7183 farm 8 title {Gedi Ruins, Local Guide} ispublic 1 isfriend 0 isfamily 0} {id 6822909640 owner 52857411@N08 secret f4e392ea36 server 7063 farm 8 title {Local Fisherman, Mida Creek} ispublic 1 isfriend 0 isfamily 0}}} stat ok
then create a pretty printed dictionary
set d2 [json::json2prettydict $jsonStr]
result is still a valid tcl-dict, just more readable
photos {
page 1
pages 726
perpage 3
total 7257
photo {
{
id 6974156079
owner 74957296@N08
secret 005d743f82
server 7197
farm 8
title {Kenya Watamu "Deep Sea Fishing" "Indian Ocean" "Blue Marlin"}
ispublic 1
isfriend 0
isfamily 0
}
{
id 6822988100
owner 52857411@N08
secret 56630c18e8
server 7183
farm 8
title {Gedi Ruins, Local Guide}
ispublic 1
isfriend 0
isfamily 0
}
{
id 6822909640
owner 52857411@N08
secret f4e392ea36
server 7063
farm 8
title {Local Fisherman, Mida Creek}
ispublic 1
isfriend 0
isfamily 0
}
}
}
stat ok
EF For an experiment on how to access data from the "parsed tree" (which really are dictionaries), see
Playing XPath with JSON.
Write JSON edit
Convert a dictionary into a JSON object
DcK 2017-10-16 To communicate with a REST API, I need to send a JSON payload, initially available in TCL code as a dictionary.
The
::json::write object nicely solves this problem, but expects the values already to be valid JSON data. So if you accept the paradigm "everything is a string", and want to encode everything as a string, you can use:
proc dict2json {dictToEncode} {
::json::write object {*}[dict map {k v} $dictToEncode {
set v [::json::write string $v]
}]
}
To go beyond the "all values are strings" paradigm, the map script code has to write something else according your rules.
Performance edit
dbohdan 2015-03-23: Tcllib JSON gets a significant speed boost from
[jsonc
] if you have
tcllibc and
critcl installed.
Change Log edit
JH 2006-08-17: I have made the JSON parser functional and moved it into tcllib (see
http://tcllib.cvs.sourceforge.net/tcllib/tcllib/modules/json/). I started with what
CMcC had here, but rewrote it for correctness and improved speed.