bvstone

Parsing JSON using RPG with Scott Klement's Port of YAJL (Yet Another JSON Library)

Posted:

Parsing JSON using RPG with Scott Klement's Port of YAJL (Yet Another JSON Library)

In a previous article we showed an example of how you can build JSON very easily using Scott Klement's port of the YAJL JSON Library.

In this three part article we will focus on parsing the JSON data.

The data we will be working with in the two examples will be the same data that we built in the previous article on building JSON.

The first example was JSON data that represented our customer records.  The data was presented in a JSON array object with each array element representing one customer's information:

{
    "customerList": [
        {
            "email": "customer1@email.com",
            "lname": "LastName",
            "fname": "FirstName",
            "comp": "Company, Inc.",
            "add1": "Address1",
            "add2": "Address2",
            "city": "Eugene",
            "state": "OR",
            "zip": "97401",
            "country": "USA"
         },
         {
            "email": "customer2@email.com",
            "lname": "LastName",
            "fname": "FirstName",
            "comp": "Company, Inc.",
            "add1": "Address1",
            "add2": "Address2",
            "city": "Fargo",
            "state": "ND",
            "zip": "58201",
            "country": "USA"
         },
        ....
    ]
}

To parse this data we will need to loop through each element in the array and process each array element.  

The following program was what we came up with (using the samples provided as a starting point):

     H DFTACTGRP(*NO) BNDDIR('YAJL')
      ****************************************************************
      * Imports
      ****************************************************************
      /include yajl_h
      ****************************************************************
      * Global Definitions
      ****************************************************************
     D CSTMSTDS      E DS                  EXTNAME(CSTMSTPF)
      ****************************************************************
      * Work Variables
      ****************************************************************
     D docNode         s                   like(yajl_val)
     D custList        s                   like(yajl_val)
     D node            s                   like(yajl_val)
     D val             s                   like(yajl_val)
      *
     D i               s             10i 0
     D errMsg          s            500a   varying inz('')
      ****************************************************************
      /free

       docNode = yajl_stmf_load_tree( '/tmp/makejson1.json' : errMsg );

       if errMsg <> '';
          // handle error
       endif;

       exsr $Header;

       yajl_tree_free(docNode);

       *inlr = *on;
       //***************************************************************
       //* Read Header
       //***************************************************************
       begsr $Header;

         custList = YAJL_object_find(docNode: 'customerList');

         i = 0;

         dow YAJL_ARRAY_LOOP(custList:i:node );
            val = YAJL_object_find(node:'email');
            CMEMAIL = yajl_get_string(val);

            val = YAJL_object_find(node: 'lname');
            CMLNAME = yajl_get_string(val);

            val = YAJL_object_find(node: 'fname');
            CMFNAME = yajl_get_string(val);

            val = YAJL_object_find(node: 'comp');
            CMFCOMP = yajl_get_string(val);

            val = YAJL_object_find(node: 'add1');
            CMFADD1 = yajl_get_string(val);

            val = YAJL_object_find(node: 'add2');
            CMFADD2 = yajl_get_string(val);

            val = YAJL_object_find(node: 'city');
            CMFCITY = yajl_get_string(val);

            val = YAJL_object_find(node: 'state');
            CMFSTATE = yajl_get_string(val);

            val = YAJL_object_find(node: 'zip');
            CMFZIP = yajl_get_string(val);

            val = YAJL_object_find(node: 'country');
            CMFCNT = yajl_get_string(val);
         enddo;

       endsr;

In the D-Specs we first see a few variables defined "like" yajl_val.  These are pointers that will be used to point to the beginning of each JSON object that we process.  Think of these pointers as 
"holding places" so we know where we are in the JSON structure.  Similar to when you're reading a book and you put a finger on the first paragraph, then as you read each word use your other finger to follow the words in the paragraph.

The first variable, docNode, is used to point to the very beginning of the JSON data.  Once we load the JSON data using yajl_stmf_load_tree() the docNode pointer will point to the start of the data.  

Next, we need to find the beginning of the first element in the data.  In this case it's an array named customerList and will point to the beginning of the array of customer data JSON objects.  We find the start using the YAJL_object_find() procedure.

The YAJL_object_find() procedure accepts 2 parameters

  1. An input parameter that should be a pointer to the parent object (in this case, the entire JSON data set)
  2. The name of the node we want to find (in this case, customerList)

If found, a pointer to the object will be returned.  If not found, the pointer value will be *NULL.

Once we find the customer array we need to loop through each item and process them.  This is done with a very interesting procedure named YAJL_ARRAY_LOOP().  This procedure takes 3 parameters:

  1. An input parameter that is a pointer to the beginning of the array to process.  In this case, it should be the pointer we found earlier that points to the beginning of the customer array, customerList.
  2. An input/output parameter that is the current index being processed (that should be set to zero before processing).  This index is incremented automatically on each iteration of the loop by the procedure itself.  In our case this is a variable named i.
  3. A output parameter that holds a pointer to the current array element that is being processed.  This is important when we want to find information for the specific array element.  In our case this pointer will be named node.

For each item in the array we process them by using the YAJL_object_find() procedure and the name of each item in the customer object we want to get the data for.  It's important to note that the name of the node we are using for each piece of customer data is node.  This is the parameter returned from the YAJL_ARRAY_LOOP() call that was executed previously.

Take a look at this figure for a visual representation of what is happening:

So, right now we have 3 pointers.  docNode and customerList are reference points in the JSON data for the entire document and the beginning of the customer list, respectively.  

The third pointer, node travels down each array element of the customer list as we loop through.  This means we will have access to the data in each node and the data can be processed normally.

This example is a very simple one, and in the Part 2 of this series we will be processing another set of data that includes embedded arrays more than one level deep.

Related Articles:


Last edited 07/12/2019 at 10:52:09



Latest Posts:

Calculating the Size of a File Before Base64 Encoding Calculating the Size of a File Before Base64 Encoding
Posted by August 13, 2022
Programming >> RPG Programming
GreenTools for Microsoft Apps (G4MS) v9.12 Now Includes Function to Send Emails using MIME File GreenTools for Microsoft Apps (G4MS) v9.12 Now Includes Function to Send Emails using MIME File
Posted by August 11, 2022
BVSTools >> BVSTools Announcements >> GreenTools for Microsoft Apps (G4MS) Specific Announcements
GreenTools for Google Apps (G4G) v15.20 Now Supports Shortcuts GreenTools for Google Apps (G4G) v15.20 Now Supports Shortcuts
Posted by August 6, 2022
BVSTools >> BVSTools Announcements >> GreenTools for G Suite (Google Apps) (G4G) Specific Announcements
GreenTools for Microsoft Apps (G4MS) Groups Admin Authority Instructions GreenTools for Microsoft Apps (G4MS) Groups Admin Authority Instructions
Posted by July 26, 2022
BVSTools >> BVSTools Software Discussion >> GreenTools for Microsoft Apps (G4MS) Specific Discussion
GreenTools for Microsoft Apps (G4MS) v9.10 Now Includes OneDrive Functions that Work With Groups/Shared Drives GreenTools for Microsoft Apps (G4MS) v9.10 Now Includes OneDrive Functions that Work With Groups/Shared Drives
Posted by July 19, 2022
BVSTools >> BVSTools Announcements >> GreenTools for Microsoft Apps (G4MS) Specific Announcements
GreenTools for Google Apps (G4G) v15.10 Now Includes Drive Functions that Work With Shared Drives GreenTools for Google Apps (G4G) v15.10 Now Includes Drive Functions that Work With Shared Drives
Posted by July 15, 2022
BVSTools >> BVSTools Announcements >> GreenTools for G Suite (Google Apps) (G4G) Specific Announcements
GreenTools for Microsoft Apps (G4MS) v9.00 Now Offers Functions to Bypass Registration Command and BVSTools Landing Page GreenTools for Microsoft Apps (G4MS) v9.00 Now Offers Functions to Bypass Registration Command and BVSTools Landing Page
Posted by July 4, 2022
BVSTools >> BVSTools Announcements >> GreenTools for Microsoft Apps (G4MS) Specific Announcements
What Objects Should I Omit from Replication to Ensure My License Keys Work on my HA/DR System? What Objects Should I Omit from Replication to Ensure My License Keys Work on my HA/DR System?
Posted by June 27, 2022
BVSTools >> BVSTools Software Discussion
GreenTools for Google Apps (G4G) v15.00 Now Offers Functions to Bypass Registration Command and BVSTools Landing Page GreenTools for Google Apps (G4G) v15.00 Now Offers Functions to Bypass Registration Command and BVSTools Landing Page
Posted by May 3, 2022
BVSTools >> BVSTools Announcements >> GreenTools for G Suite (Google Apps) (G4G) Specific Announcements
How Do I Switch From MAILTOOL Plus to GreenTools for Google or Microsoft Office 365? How Do I Switch From MAILTOOL Plus to GreenTools for Google or Microsoft Office 365?
Posted by April 18, 2022
BVSTools >> BVSTools Software Discussion >> Email Tools (MAILTOOL) Specific Discussion
PTFs Issued for SSL/TLS Issues PTFs Issued for SSL/TLS Issues
Posted by March 12, 2022
IBM Power Systems >> PTF Watch
Google Dropping Support for Google Dropping Support for "Less Secure Apps" May 30th, 2022. What Does This Mean for Your IBM i Email?
Posted by March 4, 2022
BVSTools >> BVSTools Software Discussion >> Email Tools (MAILTOOL) Specific Discussion
Have You Installed a New Version of MAILTOOL and Now Things Are Acting Different?  Check the Command Defaults! Have You Installed a New Version of MAILTOOL and Now Things Are Acting Different? Check the Command Defaults!
Posted by February 28, 2022
BVSTools >> BVSTools Software Discussion >> Email Tools (MAILTOOL) Specific Discussion
Using MAILTOOL Plus on V7R1, or Any OS Using TLS 1.1 or Older Using MAILTOOL Plus on V7R1, or Any OS Using TLS 1.1 or Older
Posted by January 27, 2022
BVSTools >> BVSTools Software Discussion >> Email Tools (MAILTOOL) Specific Discussion
BVSTools ILE Functions Being Updated to Remove Hashtag (#) from Function Names BVSTools ILE Functions Being Updated to Remove Hashtag (#) from Function Names
Posted by December 30, 2021
BVSTools >> BVSTools Announcements

Reply




Copyright 1983-2020 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).