Forum OpenACS Development: JSON parser for TCL/NaviServer

The repository is here: https://github.com/jerily/tjson

It is only tested on linux (Ubuntu). I welcome feedback and pull requests to get this working on other platforms.

It supports two kinds of parsing, namely simple and typed. For example:

Simple:


::tjson::parse {{"a": 1, "b": true, "c": [1, 2, 3], "d": {"d1":"a", "d2":"b"}}} true
=> a 1 b 1 c {1 2 3} d {d1 a d2 b}

Typed:


::tjson::parse {{"a": 1, "b": true, "c": [1, 2, 3], "d": {"d1":"a", "d2":"b"}}}
=> M {a {N 1} b {BOOL 1} c {L {{N 1} {N 2} {N 3}}} d {M {d1 {S a} d2 {S b}}}}

And if you have a typed spec like the one returned from the last example, you can serialize it back to json.

Serializing to JSON:


::tjson::to_json {M {a {N 1} b {BOOL 1} c {L {{N 1} {N 2} {N 3}}} d {M {d1 {S a} d2 {S b}}}}}
=> {"a": 1, "b": true, "c": [1, 2, 3], "d": {"d1": "a", "d2": "b"}}

This is under the MIT license but if anyone needs an LGPL one, I have another project just for that and it is kind of easier to install in the sense that you don't have to build any dependencies for it.

Collapse
Posted by Neophytos Demetriou on
Greetings to all,

We are getting close to releasing the first version of tjson. I have added JSON manipulation commands very much like what tDOM does with XML. Please note that I had to change the command names in my original post to json_to_simple, json_to_typed, and typed_to_json to accommodate the manipulation commands.

Here is a quick example:

package require tjson

set node_handle [::tjson::parse { { "store": { "book": [ { "category": "reference", "author": "Nigel Rees", "title": "Sayings of the Century", "price": "8.95" }, { "category": "fiction", "author": "Evelyn Waugh", "title": "Sword of Honour", "price": "12.99" }, { "category": "fiction", "author": "Herman Melville", "title": "Moby Dick", "isbn": "0-553-21311-3", "price": "8.99" }, { "category": "fiction", "author": "J. R. R. Tolkien", "title": "The Lord of the Rings", "isbn": "0-395-19395-8", "price": "22.99" } ], "bicycle": { "color": "red", "price": "19.95" } } }}]

set store_handle [::tjson::get_object_item $node_handle store] ::tjson::add_item_to_object $store_handle car [list M \ [list brand {S "Mercedes"} color {S blue} price {N 19876.57}]]

set book_handle [::tjson::get_object_item $store_handle book] ::tjson::add_item_to_array $book_handle [list M \ [list \ category {S "fiction"} \ author {S "Fyodor Dostoevsky"} \ title {S "Brothers Karamazov"} \ isbn {S "0679410031"} \ price {N "22.19"}]]

puts [::tjson::to_pretty_json $node_handle] ::tjson::destroy $node_handle

And here is the output:

{
  "store": {
    "book": [
      {
        "category": "reference",
        "author": "Nigel Rees",
        "title": "Sayings of the Century",
        "price": "8.95"
      },
      {
        "category": "fiction",
        "author": "Evelyn Waugh",
        "title": "Sword of Honour",
        "price": "12.99"
      },
      {
        "category": "fiction",
        "author": "Herman Melville",
        "title": "Moby Dick",
        "isbn": "0-553-21311-3",
        "price": "8.99"
      },
      {
        "category": "fiction",
        "author": "J. R. R. Tolkien",
        "title": "The Lord of the Rings",
        "isbn": "0-395-19395-8",
        "price": "22.99"
      },
      {
        "category": "fiction",
        "author": "Fyodor Dostoevsky",
        "title": "Brothers Karamazov",
        "isbn": "0679410031",
        "price": 22.19
      }
    ],
    "bicycle": {
      "color": "red",
      "price": "19.95"
    },
    "car": {
      "brand": "Mercedes",
      "color": "blue",
      "price": 19876.57
    }
  }
}

The only things pending for the release of the first version are:

  1. Tests
  2. Refactor escape_json_string
  3. Build the library on macOS

Once the release is out, I will try to add JSONPATH support.

As usual, any feedback or pull requests are more than welcome.

PS. I told a friend that I had built an extension for parsing JSON in TCL and the first question he asked was how you were all performing API calls to the backend from the frontend (he comes from the Node.js/React/Typescript world) and the answer is I do not know but my best guess is that you did not make any. I would greatly appreciate it if someone could enlighten me.

Collapse
Posted by Neophytos Demetriou on
The first version is out. It includes commands for:
  • (a) Simple transformations between TCL and JSON with the typed notation (L for list, M for object or map, S for string, N for number, and BOOL for boolean)
  • (b) Manipulate objects and arrays (add, replace, and delete items and elements) in the JSON.
  • (c) Perform JSONPath queries (NEW)
  • (d) Serialize to JSON, pretty JSON, or a simple TCL structure i.e. string, list, and dict.

NOTES: I have yet to test on macOS. To be honest, I am still debating with myself whether to buy a mac laptop for this or let the community test and provide feedback. I have a feature request that will hopefully go in with the next version (it is completely independent and incremental to the current version). If someone is willing to explain or provide links how they build server modules on Windows, I will gladly support Windows as well. For the time being, tjson has been tested on Linux.