Creating JSON objects

3,292 views
Skip to first unread message

Steve Singh

unread,
Jan 4, 2011, 10:47:42 PM1/4/11
to Jansson users
Hello,

I just started using Jansson and so far everything's been great. I've
only had to extract out name/value pairs from already defined objects,
but now I've have to create a brand new object from scratch. I need
to create something like this:

{
"ComputerListing" : {
"Name" : "STX",
"Ports" : [{"Address" : "Serial1"}, {"Address" : "Parallel1"},
{"Address" : "Parallel2" }]
}
}

The problem is, I'm having trouble visualizing this. Do I need first
need to start creating the Ports array, then json_array_append() the
individual name/value pairs? Or do I create it "top down"? Is there
an example of JSON object creation that I can look at? I guess I keep
getting confused about key/value and actual JSON pairs.

Also, since I have to do a few json_object() calls to create the
different elements, I'm assuming I only need to one json_decref at
the root object (in other words, json_decref will traverse the entire
"tree" of JSON objects and free everything?)

Sorry if I'm asking very basic questions, still trying to get the hang
of this and I googled around and couldn't find any sample code.

Thanks!

Steve

Petri Lehtinen

unread,
Jan 5, 2011, 1:53:14 AM1/5/11
to jansso...@googlegroups.com
Steve Singh wrote:
> I just started using Jansson and so far everything's been great. I've
> only had to extract out name/value pairs from already defined objects,
> but now I've have to create a brand new object from scratch. I need
> to create something like this:
>
> {
> "ComputerListing" : {
> "Name" : "STX",
> "Ports" : [{"Address" : "Serial1"}, {"Address" : "Parallel1"},
> {"Address" : "Parallel2" }]
> }
> }
>
> The problem is, I'm having trouble visualizing this. Do I need first
> need to start creating the Ports array, then json_array_append() the
> individual name/value pairs? Or do I create it "top down"? Is there
> an example of JSON object creation that I can look at? I guess I keep
> getting confused about key/value and actual JSON pairs.

The order doesn't really matter. Do it as feels right to you. I'd do
it bottom up:

int i;
const char *addrs[] = {"Serial1", "Parallel1", "Parallel2"};

json_t *root, *computer_listing, *ports;

ports = json_array();
for(i = 0; i < 3; i++) {
json_t *tmp = json_object();
json_object_set_new(tmp, "Address", json_string(addrs[i]));
json_array_append_new(ports, tmp);
}

computer_listing = json_object();
json_object_set_new(computer_listing, "Name", json_string("STX"));
json_object_set_new(computer_listing, "Ports", ports);

root = json_object();
json_object_set_new(root, "ComputerListing", computer_listing);

This first creates the Ports array and adds members to it in the for
loop. It then creates the ComputerListing object and adds Name and
Ports to it. Finally it creates the root object and adds
ComputerListing to it.

> Also, since I have to do a few json_object() calls to create the
> different elements, I'm assuming I only need to one json_decref at
> the root object (in other words, json_decref will traverse the entire
> "tree" of JSON objects and free everything?)

json_decref() will traverse and recursively decref everything, so a
single call json_decref(root) is enough at the end, but you need to
be careful to not leave the references you created yourself hanging.

See my code above. It uses the "_new" functions to add values to
containers. For example:

json_object_set_new(computer_listing, "Name", json_string("STX"));

This is equivalent to:

json_t *tempstring = json_string("STX");
json_object_set_new(computer_listing, "Name", tempstring);

After the call to json_string(), tempstring points to a new reference.
json_object_set_new() _steals_ that reference when adding tempstring
to the computer_listing object. This is equivalent to:

json_t *tempstring = json_string("STX");
json_object_set(computer_listing, "Name", tempstring);
json_decref(tempstring);

Note that this time the function json_object_set() was used instead of
json_object_set_new(). json_object_set() is a good citizen and
increments the reference count of tempstring because it stores
tempstring inside itself. So in this case you need to decrement the
reference count for the reference you created yourself by calling
json_string().

I hope this makes sense. The reference counting and the differences
between the "_new" and "normal" function variants are documented in:

http://www.digip.org/jansson/doc/1.3/apiref.html#reference-count

> Sorry if I'm asking very basic questions, still trying to get the hang
> of this and I googled around and couldn't find any sample code.

Unfortunately, the tutorial doesn't cover value creation or
manipulation at all. This should be fixed at some point, as the
reference counting is the hardest part of Jansson to grasp if the
concept is new to the user.

Petri

Steve Singh

unread,
Jan 6, 2011, 2:04:53 AM1/6/11
to Jansson users
Thanks so much for your detailed response Petri. Your sample code made
me understand it perfectly! Yes, I think I understand the reference
counting and being careful with new references vs stolen ones.

Also, thanks for all of your hard work on Jansson! If I'm ever in
Finland (again, I was there on holiday in '02), I'll buy you a
beer! :)

Steve
Reply all
Reply to author
Forward
0 new messages