在IBM i(V7.3)上使用RPG和YAJL或DB2-SQL分解作为数组接收的整个Json文件

时间:2018-07-24 18:10:08

标签: sql json db2 rpgle yajl

我对IBM i(7.3)上的Web服务和Json有点陌生,并且不确定如何使用RPG和YAJL分解以下Json文件(见下文)。

我要分解的Json IFS文件不适合标头信息,数组信息等的“常规”格式(在我没有分解问题的地方)。

换句话说,(如果我错了,请纠正我),Json对象包装在此文件的数组中。

因此,整个Json文件是一个数组,需要加载到一个或多个索引条目的数组中(此Web服务响应中的dim = 1。)。

我将如何使用YAJL或DB2-SQL从IFS分解RPG中的Json文件,以获得所有数据元素进行处理?

•   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.).   

我们将不胜感激。

谢谢。

[{
   "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;                       

1 个答案:

答案 0 :(得分:0)

我目前没有时间为您提供完整的解决方案,但是听起来您的主要问题是数组的初始值。答案实际上非常简单。您可以在初始docnode上使用YAJL_array_loop来遍历该初始数组,如下所示:

...
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;  

在这种情况下,无需在初始节点上调用YAJL_object_find,因为在加载树时您已经具有相关的数组值。还有其他可能的解决方案,例如,将DATA-INTOYAJLINTO解析器一起使用,或在DB2 SQL中使用JSON_TABLE,但这足以使您如愿以偿。