&|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 6. Discussion **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 **Summary** ... your comments