Forums >> Programming >> Proof of Concept (POC) >>
Parsing JSON Arrays with RPG and JSONTOOL




Posted:
bvstone

Parsing JSON Arrays with RPG and JSONTOOL

 
Parsing JSON Arrays with RPG and JSONTOOL

You will no doubt run into issues where the JSON data you are working with starts with an array, and not an object.

Because the JSON spec allows starting data with an object or an array, you will need to know how JSONTOOL handles each.  When the data starts with an object, the previous examples apply.  But data that starts with an array has a special circumstance that should be noted.

[
  {"phone_contact" : "123-456-7890"}, 
  {"phone_contact" : "234-567-8901"}, 
  {"phone_contact" : "345-678-9012"}, 
  {"phone_contact" : "456-789-0123"}
]

As you can see, the data starts with a bracket "[" representing that the data set is an array of objects instead of a curly bracket "{" which represents an object.

When data like this is loaded into JSONTOOL (using the newer F.JSON2 subprocedures) the data is automatically "wrapped" in one object named "data".   Below is an example of the end result:

{"data":
  [
    {"phone_contact" : "123-456-7890"}, 
    {"phone_contact" : "234-567-8901"}, 
    {"phone_contact" : "345-678-9012"}, 
    {"phone_contact" : "456-789-0123"}
  ]
}

The reason for this is to keep the functionality of the parser consistent.

If we wanted to read the value of the first element in the array, we would use the following:

tag = 'data[1]:phone_contact';                 
#js2_setValue('tag':tag);                   
phoneNumber = #js2_getDataStr();                

We will also run into issues where we aren't told the number of elements in an array.  In this case we need to loop through reading the data until blank is returned.

i = 1;
tag = 'data[' + %char(i) +']:phone_contact';                 
#js2_setValue('tag':tag);                   
phoneNumber(i) = #js2_getDataStr();

dow (phoneNumber(i) <> ' ');
  i += 1;
  tag = 'data[' + %char(i) +']:phone_contact';                 
  #js2_setValue('tag':tag);                   
  phoneNumber(i) = #js2_getDataStr();
enddo;

Think of this as a method of using a "priming read" before entering the loop.  Something I've done since college after doing it another way caused some issues I'd rather not remember.  :)  There are other ways to do this, but this is how I choose to.

Multi-Dimensional Arrays

In JSON you can also have arrays in your arrays!  Parsing this type of data is similar.  Let's assume the following data:

[
  {"phone_contact" : "123-456-7890"}, 
  {"phone_contact" : "234-567-8901",
   "aliases" : [
     {"name" : "jezza"}, 
     {"name" : "clarkson"}, 
     {"name" : "jeremy"}
   ]},
  {"phone_contact" : "345-678-9012"}, 
  {"phone_contact" : "456-789-0123"}
]

In this example, the 2nd element has another array of objects that describe aliases of the contact, in this case BBC's infamous Jeremy Clarkson of Top Gear ("brilliant", I know).

If we wanted to retrieve the name of the 1st alias (jezza) in the 2nd object (the only one with the alias array), we would use the following:

tag = 'data[2]:aliases[1]:name';                 
#js2_setValue('tag':tag);                   
alias = #js2_getDataStr();    

If we wanted to retrieve the 2nd alias (clarkson) in the 2nd object, we would use the following:

tag = 'data[2]:aliases[2]:name';                 
#js2_setValue('tag':tag);                   
alias = #js2_getDataStr();  

As you can see, we again denote the array element using a number inside of brackets after the object.

All simple enough.  Programming to read this data again can be done by looping (inside your main loop) to load each alias instance.

Interestingly enough, we see here that JSON doesn't really allow us to create an array inside of an object that does not have a name associated with it.  As we saw in the first example, that can only occur when the array is the start of the data.  To me, that is inconsistent, especially for JSON parsers.  That is why we chose to go the route of wrapping arrays in an object before starting to parse.

 


Last edited 05/30/2015 at 07:47:00


Reply




Copyright 1983-2017 BVSTools
GreenBoard(v3) Powered by the eRPG SDK, MAILTOOL Plus!, GreenTools for Google Apps, jQuery, jQuery UI, BlockUI, CKEditor and running on the IBM i (AKA AS/400, iSeries, System i).