Thread overview
Tango JSON Parser: Accessing the members
Aug 16, 2008
Benji Smith
Aug 16, 2008
Benji Smith
Aug 17, 2008
Moritz Warning
Re: Tango JSON Parser: Accessing the members [Phobos Alternative]
Aug 17, 2008
Alan Knowles
August 16, 2008
I've been trying out the new tango JSON parser, and the functionality for actually parsing the string is very easy to invoke. But I can't figure out, for the life of me, how to read the individual children of the resultant object hierarchy.

Here's what I've got:

module mymodule;

import tango.text.json.Json;

void main() {

  char[] json = `{"t": true}`;

  auto parser = new Json!(char);

  // "Error: identifier 'JsonValue' is not defined"
  JsonValue* jsonValue = p.parse(json);

  // "Error: identifier 'JsonObject' is not defined"
  JsonObject jsonObject = p.parse(json).toObject();

  // "Error: identifier 'Composite' is not defined"
  Composite composite = p.parse(json).toObject();

}

I'm sure I'm missing something from my 'import' declarations, but I've tried adding "tango.text.json.JsonValue" or "tango.text.json.Json.JsonValue" or "tango.text.json.Json.Composite" and the compiler has not been happy with any of those (each of which is a struct or an alias defined within the Json class).

Has anyone else tinkered with the JSON stuff yet? Any ideas?

Thanks!

--benji
August 16, 2008
Incidentally...

I recently wrote a JSON parser in Java, and my implementation included a "JsonSelector" class, for applying an XPath-like syntax to a JSON hierarchy and selecting nodes from the tree. Kind of like this:

  JsonNode rootJson = JsonParser.parse(text);

  Collection<JsonNode> grandchildren = JsonSelector.select(
    "/root/child/*", rootJson
  );

  JsonNode thirdChild = JsonSelector.selectSingleNodeOrNull(
    "/root/child[3]", rootJson
  );

  Collection<JsonNode> allDocNodes = JsonSelector.select(
    "/*/doc", rootJson
  );

I'd like to contribute a similar class to the Tango JSON parser, if others are interested, once I can figure out how to implement a simple visitor pattern over the tango json objects.

--benji
August 17, 2008
On Sat, 16 Aug 2008 19:31:20 -0400, Benji Smith wrote:

> I've been trying out the new tango JSON parser, and the functionality for actually parsing the string is very easy to invoke. But I can't figure out, for the life of me, how to read the individual children of the resultant object hierarchy.
> 
> Here's what I've got:
> 
> module mymodule;
> 
> import tango.text.json.Json;
> 
> void main() {
> 
>    char[] json = `{"t": true}`;
> 
>    auto parser = new Json!(char);
> 
>    // "Error: identifier 'JsonValue' is not defined" JsonValue*
>    jsonValue = p.parse(json);
> 
>    // "Error: identifier 'JsonObject' is not defined" JsonObject
>    jsonObject = p.parse(json).toObject();
> 
>    // "Error: identifier 'Composite' is not defined" Composite composite
>    = p.parse(json).toObject();
> 
> }
> 
> I'm sure I'm missing something from my 'import' declarations, but I've tried adding "tango.text.json.JsonValue" or "tango.text.json.Json.JsonValue" or "tango.text.json.Json.Composite" and the compiler has not been happy with any of those (each of which is a struct or an alias defined within the Json class).
> 
> Has anyone else tinkered with the JSON stuff yet? Any ideas?
> 
> Thanks!
> 
> --benji

Use

auto value = p.parse(json);

or

Json!(char).Value value = p.parse(json);

or

Json!(char).JsonValue* value = p.parse(json);

August 17, 2008
I needed a JSON encoder/decoder the other day as well, since I'm Phobos based, rather than Tango based. and am not that keen on introducing Templates into my code (as they tend to make the code extremely difficult to read for me)

You can grabe the source here..

http://www.akbkhome.com/svn/D_Stuff/json.d

Caveats  (although if someone wants to fix and send me it I add it)
- Unicode support is incompatible with JSON (it just uses \xHH rather than /uHHHH
- No Complex Number support (only ulong/uint are really supported
- It should support streams for encoding/decoding... but does not... (should be quite trivial to add though)

As the examples show, the code is designed for object serialization and storage.  and making that code as simple and easy to write/maintain.


Examples:

f.write(jSomething(obj).encode());

JsonValue jSomething(something t) {
	  auto x = jsonO(); // make a json object
	  x.add('fred', t.fred);  // for all the properties do this...
                                 //(that are of normal types...)
	  x.add('blogs', t.blogs);
	
	  x.add('someobj', t.someobj.toJSON());
                                              // an property that's an
                                              // object for example...
	
	  auto y = jsonA(); // create a new array
	  foreach(a;t.b) {
		  y.add(a);
	  }
	  x.add('b', y); // add the array.
	  return x;
  }

and decoding...

JsonValue x = jsonDecode(mystring);

    myobj fromJSON(JsonValue x) {
	  auto t = new myobj(); // create the return obj.

          // copy the serialize code, and replace add with get!!!!
	  x.get('fred', t.fred);
	  x.get('blogs', t.blogs);
	
	
	  t.someobj = x.getO('someobj');
                            // object getting a little difffernt.
	
	  auto a = x.getA('b');
	  for (int i=0; i < a.length(); i++ ){
			t.b ~= a.getS(i);
                       //// explicit type get an array object value....
		}
	
  }







Benji Smith wrote:
> I've been trying out the new tango JSON parser, and the functionality for actually parsing the string is very easy to invoke. But I can't figure out, for the life of me, how to read the individual children of the resultant object hierarchy.
> 
> Here's what I've got:
> 
> module mymodule;
> 
> import tango.text.json.Json;
> 
> void main() {
> 
>   char[] json = `{"t": true}`;
> 
>   auto parser = new Json!(char);
> 
>   // "Error: identifier 'JsonValue' is not defined"
>   JsonValue* jsonValue = p.parse(json);
> 
>   // "Error: identifier 'JsonObject' is not defined"
>   JsonObject jsonObject = p.parse(json).toObject();
> 
>   // "Error: identifier 'Composite' is not defined"
>   Composite composite = p.parse(json).toObject();
> 
> }
> 
> I'm sure I'm missing something from my 'import' declarations, but I've tried adding "tango.text.json.JsonValue" or "tango.text.json.Json.JsonValue" or "tango.text.json.Json.Composite" and the compiler has not been happy with any of those (each of which is a struct or an alias defined within the Json class).
> 
> Has anyone else tinkered with the JSON stuff yet? Any ideas?
> 
> Thanks!
> 
> --benji