&|What|build JSON with tdom using '''''createNodeCmd'''''|&
&|Requires|tdom 0.9.2|&
&|tags|tdom|&
&|reference|http://www.tdom.org/index.html/doc/trunk/doc/index.html|&
&|Updated|03.07.2022|&
----
**Index**
1. Challenge
2. insufficient Approach
3. Issues and Improvements
4. improved Approvements
5. Summary
**Challenge**
how to build a JSON like this:
======
{
"aNumber": 0.123,
"aNumberAsString": "0.123",
"aString": "this is a String",
"a key with spaces": "please take care on setting: dom setNameCheck 0",
"aArray": ["a","b","c"],
"aObject": {
"foo":"that",
"bar":"grill"
},
"aObjectArray": [
{
"foo": "objArray_01_foo",
"bar": "objArray_01_bar",
"array": ["five_01_a", "five_01_b", "five_01_c"]
},
{
"foo": "objArray_02_foo",
"bar": "objArray_02_bar",
"array": ["five_02_a", "five_02_b", "five_02_c"]
}
]
}
======
**insufficient Approach**
======
#
# --- load tdom ---
#
package require tdom 0.9 ;# current version: 0.9.2 (May, 2022)
puts "tdom: [package versions tdom]"
#
# http://www.tdom.org/index.html/file?name=tests/domjson.test&ci=release
#
#
set doc [dom createDocumentNode root]
#
puts "asXML: [$root asXML -indent 4]"
puts "asJSON: [$root asJSON -indent 4]"
#
# -- aNumber --
#
set node_Number [$doc createElement "aNumber" NONE]
$node_Number appendChild [$doc createTextNode 0.123 NUMBER]
$root appendChild $node_Number
#
# -- aNumberAsString --
#
set node_StringNum [$doc createElement "aNumberAsString" NONE]
$node_StringNum appendChild [$doc createTextNode 0.123 NUMBER]
$root appendChild $node_StringNum
#
# -- aString --
#
set node_String [$doc createElement "aNumberString" NONE]
$node_String appendChild [$doc createTextNode "0.123" NUMBER]
$root appendChild $node_String
#
set node_String [$doc createElement "aString" NONE]
$node_String appendChild [$doc createTextNode "this is a String" STRING]
$root appendChild $node_String
#
# -- a key with spaces --
#
# ... you have to disable namecheck first
dom setNameCheck 0
set node_String [$doc createElement "a key with spaces" NONE]
# [dom setNameCheck] == 1 ... brings this error
# ERROR: Invalid tag name 'a key with spaces'
# while executing
# "$doc createElement "a key with spaces" NONE"
# invoked from within
# "set node_String [$doc createElement "a key with spaces" NONE]"
#
$node_String appendChild [$doc createTextNode "please take care on setting: dom setNameCheck 0" STRING]
$root appendChild $node_String
#
# -- aArray --
#
set node_Array [$doc createElement "aArray" ARRAY]
$node_Array appendChild [$doc createTextNode "a" STRING]
$node_Array appendChild [$doc createTextNode "b" STRING]
$node_Array appendChild [$doc createTextNode "c" STRING]
$root appendChild $node_Array
#
#
# -- aObject --
#
set node_Object [$doc createElement "aObject" OBJECT]
#
set node__Label [$doc createElement "foo" NONE]
set node__Value [$doc createTextNode "that" STRING]
$node_Object appendChild $node__Label
$node__Label appendChild $node__Value
#
set node__Label [$doc createElement "bar" NONE]
set node__Value [$doc createTextNode "grill" STRING]
$node_Object appendChild $node__Label
$node__Label appendChild $node__Value
#
$root appendChild $node_Object
#
#
# -- aObjectArray --
#
set node_ObjArray [$doc createElement "aObjectArray"]
#
set node__Obj_01 [$doc createElement "obj0001"]
#
set node__Label [$doc createElement "foo"]
set node__Value [$doc createTextNode "objArray_01_foo" STRING]
$node__Label appendChild $node__Value
$node__Obj_01 appendChild $node__Label
set node__Label [$doc createElement "bar"]
set node__Value [$doc createTextNode "objArray_01_bar" STRING]
$node__Label appendChild $node__Value
$node__Obj_01 appendChild $node__Label
#
set node__Array [$doc createElement "array" ARRAY]
$node__Array appendChild [$doc createTextNode "five_01_a" STRING]
$node__Array appendChild [$doc createTextNode "five_01_b" STRING]
$node__Array appendChild [$doc createTextNode "five_01_c" STRING]
#
$node__Obj_01 appendChild $node__Array
#
#
set node__Obj_02 [$doc createElement "obj0002"]
#
set node__Label [$doc createElement "foo"]
set node__Value [$doc createTextNode "objArray_02_foo" STRING]
$node__Label appendChild $node__Value
$node__Obj_02 appendChild $node__Label
set node__Label [$doc createElement "bar"]
set node__Value [$doc createTextNode "objArray_02_bar" STRING]
$node__Label appendChild $node__Value
$node__Obj_02 appendChild $node__Label
#
set node__Array [$doc createElement "array" ARRAY]
$node__Array appendChild [$doc createTextNode "five_02_a" STRING]
$node__Array appendChild [$doc createTextNode "five_02_b" STRING]
$node__Array appendChild [$doc createTextNode "five_02_c" STRING]
#
$node__Obj_02 appendChild $node__Array
#
$node_ObjArray appendChild $node__Obj_01
$node_ObjArray appendChild $node__Obj_02
#
#
$root appendChild $node_ObjArray
#
# in the case of mixed OBJECT and ARRAYs you have to update the specific rendering
$node_ObjArray jsonType ARRAY
$node__Obj_01 jsonType OBJECT
$node__Obj_02 jsonType OBJECT
#
puts "== \$resultJSON ===="
puts [$doc asXML -indent 4]
puts "== \$resultJSON ===="
puts [$doc asJSON -indent 4]
#
======
... output of this script:
======
tdom: 0.9.2
asXML:
asJSON: {}
== $resultJSON ====
0.123
0.123
0.123
this is a String
please take care on setting: dom setNameCheck 0
abc
that
grill
objArray_01_foo
objArray_01_bar
five_01_afive_01_bfive_01_c
objArray_02_foo
objArray_02_bar
five_02_afive_02_bfive_02_c
== $resultJSON ====
{
"aNumber": "0.123",
"aNumberAsString": "0.123",
"aNumberString": "0.123",
"aString": "this is a String",
"a key with spaces": "please take care on setting: dom setNameCheck 0",
"aArray": [
"a",
"b",
"c"
],
"aObject": {
"foo": "that",
"bar": "grill"
},
"aObjectArray": [
{
"foo": "objArray_01_foo",
"bar": "objArray_01_bar",
"array": [
"five_01_a",
"five_01_b",
"five_01_c"
]
},
{
"foo": "objArray_02_foo",
"bar": "objArray_02_bar",
"array": [
"five_02_a",
"five_02_b",
"five_02_c"
]
}
]
}
======
**Issues and Imoprovements**
***wrong Value***
======
this Result: "aNumber": "0.123"
expected Result: "aNumber": 0.123
======
***complex code***
... the given approach takes a lot of lines to create this result
**improved Approach**
use
======
dom createNodeCmd
======
to improve our code
======
#
# --- load tdom ---
#
package require tdom 0.9 ;# current version: 0.9.2 (May, 2022)
puts "tdom: [package versions tdom]"
#
# http://www.tdom.org/index.html/file?name=tests/domjson.test&ci=release
#
#
#
puts "== 01 == \$resultJSON ===="
set doc [dom createDocumentNode root]
#
puts "asXML: [$root asXML -indent 4]"
puts "asJSON: [$root asJSON -indent 4]"
#
#
# our targetJSON includes nodes with predefined names:
# "aNumber" "aString" "a key with spaces" "foo" "bar"
#
# ... lets predefine dom-commands to create these nodes
#
dom createNodeCmd -jsonType NONE elementNode aNumber
dom createNodeCmd -jsonType NONE elementNode aNumberAsString
dom createNodeCmd -jsonType NONE elementNode aString
dom createNodeCmd -jsonType NONE elementNode "a key with spaces"
dom createNodeCmd -jsonType NONE elementNode foo
dom createNodeCmd -jsonType NONE elementNode bar
dom createNodeCmd -jsonType NONE elementNode array
dom createNodeCmd -jsonType ARRAY elementNode "aArray"
dom createNodeCmd -jsonType OBJECT elementNode "aObject"
dom createNodeCmd -jsonType ARRAY elementNode "aObjectArray"
#
# ... json distinguishs between
# ... Arrays ["A","B","C"] and
# ... Objects {"a": "A", "b": "B", "c":"C"}
#
dom createNodeCmd -jsonType NUMBER textNode jsonNumber
dom createNodeCmd -jsonType STRING textNode jsonString
#
#
set resultJSON [dom createDocumentNode]
#
puts "== 02 == \$resultJSON ===="
puts [$resultJSON asJSON -indent 4]
#
$resultJSON appendFromScript {
aNumber {jsonNumber 0.123}
aNumberAsString {jsonString 0.123}
aString {jsonString "this is a string"}
"a key with spaces" {jsonString "It's possible."}
aArray {
jsonString a
jsonString b
jsonString c
}
aObject {
foo {jsonString "that"}
bar {jsonString "grill"}
}
aObjectArray {
aObject {
foo {jsonString "objArray_01_foo"}
bar {jsonString "objArray_01_bar"}
aArray {
jsonString "five_01_a"
jsonString "five_01_b"
jsonString "five_01_c"
}
}
aObject {
foo {jsonString "objArray_02_foo"}
bar {jsonString "objArray_02_bar"}
aArray {
jsonString "five_02_a"
jsonString "five_02_b"
jsonString "five_02_c"
}
}
}
}
#
#
puts "== 03 == \$resultJSON ===="
puts [$resultJSON asXML -indent 4]
puts "== 03 == \$resultJSON == final =="
puts [$resultJSON asJSON -indent 4]
#
======
... output of this script:
======
tdom: 0.9.2
== 01 == $resultJSON ====
asXML:
asJSON: {}
== 02 == $resultJSON ====
{}
== 03 == $resultJSON ====
0.123
0.123
this is a string
It's possible.
abc
that
grill
objArray_01_foo
objArray_01_bar
five_01_afive_01_bfive_01_c
objArray_02_foo
objArray_02_bar
five_02_afive_02_bfive_02_c
== 03 == $resultJSON == final ==
{
"aNumber": 0.123,
"aNumberAsString": "0.123",
"aString": "this is a string",
"a key with spaces": "It's possible.",
"aArray": [
"a",
"b",
"c"
],
"aObject": {
"foo": "that",
"bar": "grill"
},
"aObjectArray": [
{
"foo": "objArray_01_foo",
"bar": "objArray_01_bar",
"aArray": [
"five_01_a",
"five_01_b",
"five_01_c"
]
},
{
"foo": "objArray_02_foo",
"bar": "objArray_02_bar",
"aArray": [
"five_02_a",
"five_02_b",
"five_02_c"
]
}
]
}
======
**Summary**
* enable creating a node as a number
* createNodeCmd:
** define nodes with name and type
** create your JSON like it should look like at the end