简体   繁体   中英

Decompose whole Json file received as an array using RPG and YAJL or DB2-SQL on IBM i (V7.3)

I am sort of new with web services and Json on the IBM i (7.3), and not exactly sure how to decompose the following Json file using RPG and YAJL (See below).

The Json IFS file that I am trying to decompose does not fit the "usual" format of header info, array info etc. (Where I have no issue decomposing.).

In other words (and correct me if I am wrong), the Json objects are wrapped in an array in this file.

Therefore, the whole Json file is an array and requires to be loaded into an array of one or more index entries (dim = 1 in this web service response.).

How would I go about decomposing this Json file in RPG from the IFS using YAJL or DB2-SQL to obtain all the data elements for processing?

•   Web service file definition documentation: https://smartystreets.com/docs/cloud/us-street-api
•   RPG source with data definition is provided below (Tried a few attempts without success.).   

Any assistance and/or direction would be greatly appreciated.

Thank you.

[{
   "input_index": 0,
   "candidate_index": 0,
   "delivery_line_1": "3747 Hecktown Rd",
   "last_line": "Easton PA 18045-2350",
   "delivery_point_barcode": "180452350471",
   "components":    {
      "primary_number": "3747",
      "street_name": "Hecktown",
      "street_suffix": "Rd",
      "city_name": "Easton",
      "state_abbreviation": "PA",
      "zipcode": "18045",
      "plus4_code": "2350",
      "delivery_point": "47",
      "delivery_point_check_digit": "1"
   },
   "metadata":    {
      "record_type": "S",
      "zip_type": "Standard",
      "county_fips": "42095",
      "county_name": "Northampton",
      "carrier_route": "C042",
      "congressional_district": "15",
      "rdi": "Commercial",
      "elot_sequence": "0038",
      "elot_sort": "D",
      "latitude": 40.69648,
      "longitude": -75.28448,
      "precision": "Zip9",
      "time_zone": "Eastern",
      "utc_offset": -5,
      "dst": true
   },
   "analysis":    {
      "dpv_match_code": "Y",
      "dpv_footnotes": "AABB",
      "dpv_cmra": "N",
      "dpv_vacant": "N",
      "active": "Y"
   }
}]

++++++++++

ctl-opt dftactgrp(*no) actgrp('QILE')                  
option(*nodebugio:*srcstmt:*nounref)                   
bnddir('YAJL')  alwnull(*inputonly)                    
datfmt(*ISO) decedit('0.');                            

/include yajl/qrpglesrc,yajl_h                         

// Json IFS file to decompose.                         
dcl-c ifsFilename const('/Rick/smartstreets.json.txt');

dcl-ds jsonHeader qualified;                           
   input_id varchar(36);                               
   input_index int(10);                                
   candidate_index int(10);                            
   addressee varchar(50);                              
   delivery_line_1 varchar(50);                        
   delivery_line_2 varchar(50);                        
   last_line varchar(50);                              
   delivery_barcode varchar(12); 
   dcl-ds jsonComponents;               
      urbanization varchar(64);         
      primary_number varchar(30);       
      street_name varchar(64);          
      street_predirection varchar(16);  
      street_postdirection varchar(16); 
      street_suffix varchar(16);        
      secondary_nbr varchar(32);        
      secondary_des varchar(16);        
      extra_secondary_nbr varchar(32);  
      pmb_desinator varchar(16);        
      pmb_number varchar(16);           
      city_name varchar(64);            
      dft_city_name varchar(64);        
      state_abv char(2);                
      zipcode char(5);                  
      plus4_code varchar(4);            
      delivery_point char(2);           
      delivery_point_chk char(1);       
   end-ds;   
   dcl-ds jsonMetadata;              
      record_type char(1);           
      zip_type varchar(32);          
      county_fips char(5);           
      county_name varchar(64);       
      carrier_route varchar(4);      
      congressional_district char(2);
      building_dft_ind char(1);      
      rdi varchar(12);               
      elot_sequence varchar(4);      
      elot_sort varchar(4);          
      latitude packed(12:9);         
      longitude packed(12:9);        
      precision varchar(18);         
      time_zone varchar(48);         
      utc_offset packed(4:2);        
      dst char(5);                   
   end-ds;                           
   dcl-ds jsonAnalysis;              
      dpv_match_code varchar(1);
      dpv_footnote varchar(32);         
      ddv_cmra varchar(1);              
      dpv_vacant varchar(1);            
      active varchar(1);                
   end-ds;                              
end-ds;                                 

dcl-ds jsonResult qualified;            
   jsonArray0 likeds(jsonHeader) dim(10);
end-ds;                                 

dcl-s docnode like(yajl_val);           
dcl-s node like(yajl_val);              
dcl-s list like(yajl_val);              
dcl-s count int(10);                    
dcl-s errmsg varchar(500) inz('');      
dcl-s dspfld char(52) inz('');                                                           

// Load Json in from the IFS file.                
docnode = yajl_stmf_load_tree(ifsFilename:errmsg);

// Json loaded without issue,                     
if errmsg = '';                                   
   count = 0; 

   //Decompose IFS Json file.

  yajl_tree_free(docnode);
else;                                    
// Unable to load JSON data from the IFS.
endif;                                   

*inlr = *on;                             
return;                       

I don't have the time to give you a full solution at this time but it sounds like your main issue is the initial value being an array. The answer to that is actually pretty straightforward. You can use YAJL_array_loop on the initial docnode to loop through that initial array like so:

...
dcl-s docnode like(yajl_val);           
dcl-s node like(yajl_val);              
dcl-s list like(yajl_val);              
dcl-s count int(10);                    
dcl-s errmsg varchar(500) inz('');      
dcl-s dspfld char(52) inz('');  
dcl-s i int(5) inz;                                                         

// Load Json in from the IFS file.                
docnode = yajl_stmf_load_tree(ifsFilename:errmsg);

// Json loaded without issue,                     
if errmsg = '';                                   
   count = 0; 

   if YAJL_is_array(docnode);
      dow YAJL_array_loop(docnode: i: list);
         node = YAJL_object_find(list: 'input_index');
         jsonHeader.inputIndex = yajl_get_number(node);
         // Keep going from here...
         // You may also want to use YAJL_object_loop instead of a bunch of YAJL_object_find.
      enddo;
   endif;

  yajl_tree_free(docnode);
else;                                    
// Unable to load JSON data from the IFS.
endif;                                   

*inlr = *on;                             
return;  

In this case, there is no need to call YAJL_object_find on the initial node because you already have the relevant array value when it loads the tree. There are other possible solutions to this as well such as using DATA-INTO with the YAJLINTO parser or using JSON_TABLE in DB2 SQL but this should be enough to get you going I hope.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM