- Publicity: Public Only All
json-procs.tcl
Utility ad_procs for Tcl <-> JSON conversion. This is based on the tcllib json package written by Andreas Kupries, and later rewritten to parse via regular expressions by Thomas Maeder. The tcllib version suffers from generating Tcl structures from JSON strings with no type (JSON array or object) information. The resulting structures can't be converted back to JSON strings, you have to munge them with type information first. And the code making use the Tcl structure also needs to know whether each field is an object or array. It also depends on the DICT package or Tcl 8.5. This rewrite doesn't depend on DICT, declares procs using ad_proc (so the API will be picked up by our API browser), and is symmetrical (you can convert from JSON to the Tcl representation and back again). I've not renamed internal variables in the typical OpenACS style. I've placed these in the global util namespace for two reasons: 1. Don't want to clash with the tcllib json package in case someone else decides to use it. 2. Might put it in acs-tcl as part of the utility stuff someday. More information ... See http://www.json.org/ && http://www.ietf.org/rfc/rfc4627.txt Total rework of the code published with version number 1.0 by Thomas Maeder, Glue Software Engineering AG
- Location:
- packages/acs-tcl/tcl/json-procs.tcl
- Created:
- 2010/04/09
- Author:
- Don Baccus
- CVS Identification:
$Id: json-procs.tcl,v 1.14 2024/10/22 09:37:22 gustafn Exp $
Procedures in this file
- util::json2dict (public)
- util::json::array2json (private)
- util::json::array::create (public)
- util::json::array::get_values (public)
- util::json::gen (public)
- util::json::gen_inner (private)
- util::json::indent (public)
- util::json::json_value_to_sql_value (public)
- util::json::object2json (private)
- util::json::object::create (public)
- util::json::object::get_value (public)
- util::json::object::get_values (public)
- util::json::object::set_by_path (public)
- util::json::object::set_value (public)
- util::json::parse (public)
- util::json::parseArray (private)
- util::json::parseArrayElements (private)
- util::json::parseObject (private)
- util::json::parseObjectMember (private)
- util::json::parseObjectMembers (private)
- util::json::parseValue (private)
- util::json::sql_values_to_json_values (public)
- util::json::type_of (public)
- util::json::unexpected (private)
- util::json::unquoteUnescapeString (private)
- util::json::validate (private)
- util::tdomDoc2dict (public)
- util::tdomNodes2dict (private)
Detailed information
util::json2dict (public)
util::json2dict jsonText
Parse JSON text into a Tcl dict. This function is NOT based on the functions from the "util::json::" namespace, and is built on top of tDOM. It is a replacement for the "json::json2dict" in the tcllib package "json", but is on sample documents several times faster.
- Parameters:
- jsonText (required)
- JSON text
- Returns:
- dict containing the JSON objects represented by jsonText
- Author:
- Gustaf Neumann
- Partial Call Graph (max 5 caller/called nodes):
- Testcases:
- json_to_dict
util::json::array2json (private)
util::json::array2json arrayVal
Generate a JSON string for a two-element Tcl JSON array list.
- Parameters:
- arrayVal (required)
- [list array values]
- Returns:
- Valid JSON array string.
- Partial Call Graph (max 5 caller/called nodes):
- Testcases:
- No testcase defined.
util::json::array::create (public)
util::json::array::create values
Construct a JSON object with the given values list
- Parameters:
- values (required)
- Partial Call Graph (max 5 caller/called nodes):
- Testcases:
- No testcase defined.
util::json::array::get_values (public)
util::json::array::get_values item
Verify that the given Tcl structure is an object, and return its values list.
- Parameters:
- item (required)
- Partial Call Graph (max 5 caller/called nodes):
- Testcases:
- No testcase defined.
util::json::gen (public)
util::json::gen value
Top-level procedure to generate a JSON string from its Tcl list representation.
- Parameters:
- value (required)
- A two-element object/array Tcl list.
- Returns:
- A valid JSON string.
- Partial Call Graph (max 5 caller/called nodes):
- Testcases:
- No testcase defined.
util::json::gen_inner (private)
util::json::gen_inner value
Generate a JSON string for a sub-list of a Tcl JSON "object".
- Parameters:
- value (required)
- A list representing a JSON object/array or value
- Returns:
- Valid JSON object, array, or value string.
- Partial Call Graph (max 5 caller/called nodes):
- Testcases:
- No testcase defined.
util::json::indent (public)
util::json::indent [ -simplify ] json
Indent a JSON string to make it more easily digestable by the human mind. This works best (by far) if the JSON string doesn't already contain newlines (as will be true of JSON strings generated by util::json::gen).
- Switches:
- -simplify (optional, boolean)
- If true, remove all fields that don't contribute to the structure of the object/array combination being described by the string.
- Parameters:
- json (required)
- The string to indent
- Returns:
- The beautifully indented, and optionally simplified, string
- Partial Call Graph (max 5 caller/called nodes):
- Testcases:
- No testcase defined.
util::json::json_value_to_sql_value (public)
util::json::json_value_to_sql_value value
While mysql happily treats false as 0, real SQL does not. And we need to protect against apostrophes in strings. And handle null. You get the idea.
- Parameters:
- value (required)
- A value from a parsed JSON string
- Returns:
- Something that works in Real SQL, not to be confused with MySQL. This includes not trying to insert '' into columns of type real, when "null" is meant (we mimic Oracle bindvar/PG bindvar emulation semantics). The Ilias RTE JavaScript returns '' rather than null for JS null variables.
- Partial Call Graph (max 5 caller/called nodes):
- Testcases:
- No testcase defined.
util::json::object2json (private)
util::json::object2json objectVal
Generate a JSON string for a two-element Tcl JSON object list.
- Parameters:
- objectVal (required)
- [list object values]
- Returns:
- Valid JSON object string.
- Partial Call Graph (max 5 caller/called nodes):
- Testcases:
- No testcase defined.
util::json::object::create (public)
util::json::object::create values
Construct a JSON object with the given values list
- Parameters:
- values (required)
- Partial Call Graph (max 5 caller/called nodes):
- Testcases:
- No testcase defined.
util::json::object::get_value (public)
util::json::object::get_value -object object -attribute attribute
Returns the value of an attribute in an object. If the attribute doesn't exist, an error will result.
- Switches:
- -object (required)
- The JSON object which contains the attribute.
- -attribute (required)
- The attribute name.
- Returns:
- The attribute value or an error, if the attribute doesn't exist.
- Partial Call Graph (max 5 caller/called nodes):
- Testcases:
- No testcase defined.
util::json::object::get_values (public)
util::json::object::get_values item
Verify that the given Tcl structure is an object, and return its values list.
- Parameters:
- item (required)
- Partial Call Graph (max 5 caller/called nodes):
- Testcases:
- No testcase defined.
util::json::object::set_by_path (public)
util::json::object::set_by_path -object object -path path -value value
This is an odd utility that mimics some odd code in the Ilias SCORM module, included here because it might be of more general use. Essentially we walk down an object tree structure using the "path" parameter. If we encounter a leaf on the way, we replace it with a new object node and continue. The last element of the path is interpreted as a leaf of the tree and is set to "value". Example: util::json::gen [util::json::object::set_by_path -object "" -path {a b c} -value 3] Result: {"a":{"b":{"c":3}}} Example: util::json::gen [util::json::object::set_by_path -object [util::json::object::create [list a [util::json::object::create [list d null]]]] -path {a b c} -value 3] Result: {"a":{"b":{"c":3},"d":null}} "a" is the top level object with two subnodes "b" and "d", with "b" having a subnode "c" of value 3, and "d" being a leaf of "a" with value "null".
- Switches:
- -object (required)
- The object to add subnodes to.
- -path (required)
- The path through the tree with the last value being the name of a new or existing leaf.
- -value (required)
- The value to set the final leaf to.
- Returns:
- A new object with the new tree structure interwoven into it.
- Partial Call Graph (max 5 caller/called nodes):
- Testcases:
- No testcase defined.
util::json::object::set_value (public)
util::json::object::set_value -object object -attribute attribute \ -value value
Set an attribute value in an object structure. If the attribute doesn't exist in the object, it's created.
- Switches:
- -object (required)
- The object we want to set the value in.
- -attribute (required)
- The name of the attribute.
- -value (required)
- The value to set attribute to.
- Returns:
- A new object with the attribute/value pair.
- Partial Call Graph (max 5 caller/called nodes):
- Testcases:
- No testcase defined.
util::json::parse (public)
util::json::parse jsonText
Parse JSON text into a Tcl list.
- Parameters:
- jsonText (required)
- JSON text
- Returns:
- List containing the object represented by jsonText
- Partial Call Graph (max 5 caller/called nodes):
- Testcases:
- No testcase defined.
util::json::parseArray (private)
util::json::parseArray tokens nrTokens tokenCursorName
Parse an array
- Parameters:
- tokens (required)
- list of tokens
- nrTokens (required)
- length of $tokens
- tokenCursorName (required)
- name (in caller's context) of variable holding current position in $tokens
- Returns:
- parsed array (Tcl list)
- Partial Call Graph (max 5 caller/called nodes):
- Testcases:
- No testcase defined.
util::json::parseArrayElements (private)
util::json::parseArrayElements tokens nrTokens tokenCursorName \ resultName
Parse the elements of an array
- Parameters:
- tokens (required)
- list of tokens
- nrTokens (required)
- length of $tokens
- tokenCursorName (required)
- name (in caller's context) of variable holding current position in $tokens
- resultName (required)
- name (in caller's context) of the list representing the JSON array
- Partial Call Graph (max 5 caller/called nodes):
- Testcases:
- No testcase defined.
util::json::parseObject (private)
util::json::parseObject tokens nrTokens tokenCursorName
Parse an object
- Parameters:
- tokens (required)
- list of tokens
- nrTokens (required)
- length of $tokens
- tokenCursorName (required)
- name (in caller's context) of variable holding current position in $tokens
- Returns:
- parsed object (Tcl dict)
- Partial Call Graph (max 5 caller/called nodes):
- Testcases:
- No testcase defined.
util::json::parseObjectMember (private)
util::json::parseObjectMember tokens nrTokens tokenCursorName \ objectDictName
Parse an object member
- Parameters:
- tokens (required)
- list of tokens
- nrTokens (required)
- length of $tokens
- tokenCursorName (required)
- name (in caller's context) of variable holding current position in $tokens
- objectDictName (required)
- name (in caller's context) of dict representing the JSON object of which to parse the next member
- Partial Call Graph (max 5 caller/called nodes):
- Testcases:
- No testcase defined.
util::json::parseObjectMembers (private)
util::json::parseObjectMembers tokens nrTokens tokenCursorName \ objectDictName
Parse the members of an object
- Parameters:
- tokens (required)
- list of tokens
- nrTokens (required)
- length of $tokens
- tokenCursorName (required)
- name (in caller's context) of variable holding current position in $tokens
- objectDictName (required)
- name (in caller's context) of dict representing the JSON object of which to parse the next member
- Partial Call Graph (max 5 caller/called nodes):
- Testcases:
- No testcase defined.
util::json::parseValue (private)
util::json::parseValue tokens nrTokens tokenCursorName
Parse a value
- Parameters:
- tokens (required)
- list of tokens
- nrTokens (required)
- length of $tokens
- tokenCursorName (required)
- name (in caller's context) of variable holding current position in $tokens
- Returns:
- parsed value (dict, list, string, number)
- Partial Call Graph (max 5 caller/called nodes):
- Testcases:
- No testcase defined.
util::json::sql_values_to_json_values (public)
util::json::sql_values_to_json_values row
Converts empty values to "null", consistent with how oracle, mysql, and the nspostgres bindvar hack treats them.
- Parameters:
- row (required)
- A row (list) returned by a sql SELECT.
- Returns:
- A new list with empty strings converted to null.
- Partial Call Graph (max 5 caller/called nodes):
- Testcases:
- No testcase defined.
util::json::type_of (public)
util::json::type_of item
Return the type of the item, "object" or "array"
- Parameters:
- item (required)
- Partial Call Graph (max 5 caller/called nodes):
- Testcases:
- No testcase defined.
util::json::unexpected (private)
util::json::unexpected tokenCursor token expected
Throw an exception signaling an unexpected token
- Parameters:
- tokenCursor (required)
- token (required)
- expected (required)
- Partial Call Graph (max 5 caller/called nodes):
- Testcases:
- No testcase defined.
util::json::unquoteUnescapeString (private)
util::json::unquoteUnescapeString token
Get rid of the quotes surrounding a string token and substitute the real characters for escape sequences within it
- Parameters:
- token (required)
- Returns:
- Unquoted, unescaped value of the string contained in token
- Partial Call Graph (max 5 caller/called nodes):
- Testcases:
- No testcase defined.
util::json::validate (private)
util::json::validate jsonText
Validate JSON text
- Parameters:
- jsonText (required)
- JSON text
- Returns:
- 1 iff $jsonText conforms to the JSON grammar (@see http://json.org/)
- Partial Call Graph (max 5 caller/called nodes):
- Testcases:
- No testcase defined.
util::tdomDoc2dict (public)
util::tdomDoc2dict doc
Helper proc for util::json2dict, which outputsreturns the provided tDOM document in the form of a Tcl dict.
- Parameters:
- doc (required)
- Partial Call Graph (max 5 caller/called nodes):
- Testcases:
- No testcase defined.
util::tdomNodes2dict (private)
util::tdomNodes2dict nodes parentType
Helper proc for util::json2dict, which returns the tDOM structure in the form of a Tcl dict. Use this proc only on dom structures created with "porse -json", since it depends on the internal node structure of tDOM. It would be certainly better to have this function built-in in tDOM (call like "asDict", similar to "asXML")
- Parameters:
- nodes (required)
- parentType (required)
- Returns:
- dict
- Author:
- Gustaf Neumann
- Partial Call Graph (max 5 caller/called nodes):
- Testcases:
- No testcase defined.