18.4.0 released Sep 25, 2023
|
Read json
Purpose: Parse JSON text and get values.
read-json <json> \
( key <key> ) | ( key-list <key fragment> [ , <key fragment> ] ) \
value [ define ] <value> \
[ status [ define ] <status> ] \
[ type [ define ] <type> ]
read-json <json> traverse begin
read-json <json> traverse \
key [ define ] <key> \
value [ define ] <value> \
[ status [ define ] <status> ] \
[ type [ define ] <type> ]
read-json will obtain the values from <json> variable that was produced by parsing JSON text with new-json.
Without "traverse" clause
key/value pairs are accessed with "key" clause specifying a quoted normalized key name, which is the value's name preceded with the names of all objects and array members leading up to it, separated by a dot ("."), with each name quoted. The actual <value> is obtained with "value" clause, and the <type> of value can be obtained with optional "type" clause.
Instead of "key" clause, you can also use "key-list" clause which specifies a list of string <key fragment>s. Those fragments, when concatenated, should form the same value as <key> if "key" clause were used. If any of <key fragment>s is a NULL value, then the key ends with it. Note that a key with NULL as the very first key fragment is an invalid key.
Note that node names in JSON are always quoted, so their quotes must be escaped within a key (or a key fragment), which itself is a string between quotes. For instance, JSON key "some key" must be specified as "\"some key\"" to be a proper string. An empty key would be "\"\"".
The <status> variable in "status" clause is either VV_OKAY on success (meaning value is obtained) or VV_ERR_EXIST if not found. The value is stored in string variable <value> specified in "value" clause.
<value>, <type> and <status> can be created with optional "define".
Optional number <type> in "type" clause will contain the type of data, which can be VV_JSON_TYPE_STRING, VV_JSON_TYPE_NUMBER, VV_JSON_TYPE_REAL, VV_JSON_TYPE_BOOL or VV_JSON_TYPE_NULL for a string, integer, decimal, boolean and null value respectively.
This allows sequential access to JSON values. No key is specified, rather key/value pairs are obtained in sequence from beginning to the end. <key> can be created with optional "define". The other clauses used are the same as without "traverse".
Random access via built-in hash
You can access randomly any number, string, boolean or null value within a JSON document without having to create a matching structure in your program. Internally, Vely creates a hash table for fast and direct access to any key/value pair (see new-json).
<key> in "key" clause is a normalized name of any given leaf node in JSON text. This means every non-leaf node is included (such as arrays and objects), separated by a dot ("."), and arrays are indexed with "[]". An example would be:
"menu"."popup"."menuitem"[1]."onclick"
For instance, the above is a normalized name in this JSON text with the value of "OpenDoc()":
{"menu": {
"id": "file",
"value": "File",
"popup": {
"menuitem": [
{"value": "New", "onclick": "CreateNewDoc()"},
{"value": "Open", "onclick": "OpenDoc()"},
{"value": "Close", "onclick": "CloseDoc()"}
]
}
}
the normalized names for all leaf nodes are:
"menu"."id"
"menu"."value"
"menu"."popup"."menuitem"[0]."value"
"menu"."popup"."menuitem"[0]."onclick"
"menu"."popup"."menuitem"[1]."value"
"menu"."popup"."menuitem"[1]."onclick"
"menu"."popup"."menuitem"[2]."value"
"menu"."popup"."menuitem"[2]."onclick"
The code to parse this JSON text might then look like:
char json_text[] =\
"{\"menu\":\
{\"id\": \"file\",\
\"value\": \"File\",\
\"popup\":\
{\"menuitem\":\
[{\"value\": \"New\", \"onclick\": \"CreateNewDoc()\"},\
{\"value\": \"Open\", \"onclick\": \"OpenDoc()\"},\
{\"value\": \"Close\", \"onclick\": \"CloseDoc()\"}\
]\
}\
}\
}\n";
new-json define json_var from json_text status define st error-text define errt error-position define errp
if (st != VV_OKAY) {
@Could not parse json, error <<p-out errt>> at position <<p-num errp>>
} else {
@Json parsed okay.
}
read-json json_var key "\"menu\".\"popup\".\"menuitem\"[1].\"onclick\"" value define val status st
if (st != VV_OKAY) {
@Could not find json key
} else {
@Key value is <<p-out val>>
}
The result is:
Json parsed okay.
Key value is OpenDoc()
All values are always returned as strings. This is because in many cases that's how they are used in an application and converting them to other types (like numbers) and back again would affect performance.
Vely checks type validity - for example an invalid integer or decimal number will produce an error. If you need to convert a value to a number you can use C's library functions like atoll() or atof().
String values are returned encoded as UTF8, and any escaped characters (like \n or \t) are converted to their binary equivalent (use "noencode" in new-json to skip this). Such encoded strings can be output anywhere, from a terminal to a client (like browser).
Walk through JSON document
Use "traverse" clause to access JSON nodes sequentially, one by one, from the beginning to the end. Use "traverse begin" to rewind to the beginning, and then read data using "traverse" with "key" clause.
The following code loops through all the leaf nodes of a JSON document - you can also use it to examine a JSON document with unknown structure:
new-json define jv from json_text
read-json jv traverse begin
while (1)
{
read-json jv traverse key define k value define v type define t status define s
if (s != VV_OKAY) break;
pf-out "Name [%s], value [%s], type [%lld]\n", k, v, t
}
Obtaining a value with "key" clause:
read-json jv key "\"glossary\".\"title\"" value d
The same with "key-list" - the key can be split in any way that works for your application:
read-json jv key-list "\"glossary\"" , ".\"title\"" value d
JSON
delete-json
new-json
read-json
See all
documentation
You are free to copy, redistribute and adapt this web page (even commercially), as long as you give credit and provide a link back to this page (dofollow) - see full license at
CC-BY-4.0. Copyright (c) 2019-2023 Dasoftver LLC. Vely and elephant logo are trademarks of Dasoftver LLC. The software and information on this web site are provided "AS IS" and without any warranties or guarantees of any kind.