DATA-INTO. missing nodes name

Discussions relating to the ScottKlement.com port of the open source YAJL JSON Reader/Generator. This includes the YAJL tool as well as the YAJLR4, YAJLGEN, YAJLINTO and YAJLDTAGEN add-ons from ScottKlement.com. http://www.scottklement.com/yajl/
Scott Klement
Site Admin
Posts: 635
Joined: Sun Jul 04, 2021 5:12 am

Re: DATA-INTO. missing nodes name

Post by Scott Klement »

Here's an example of reading the document using the subprocedures... of course, this assumes that my corrections to your format are correct -- if not it may need to be adjusted, but hopefully it gives you the idea of how the "Carrier 1", "Carrier 2", etc can be used as dynamic variable data rather than using hard-coded names like you would in data-into:

Code: Select all

**free

ctl-opt dftactgrp(*no) actgrp('KLEMENT') bnddir('YAJL');

/copy YAJL_H

dcl-ds CarrierList qualified;

  num_carrier int(10) inz(0);

  dcl-ds carrier dim(999);

    name    varchar(30);
    id      varchar(6);
    service varchar(15);

  end-ds;

  validationErrors varchar(500);

end-ds;

dcl-s docNode      like(YAJL_VAL);
dcl-s errMsg       varchar(500);
dcl-s carriersNode like(YAJL_VAL);
dcl-s i            int(10);
dcl-s count        int(10);
dcl-s key          varchar(50);
dcl-s val          like(YAJL_VAL);
dcl-s msg          char(52);


// ----------------------------------------------------------
//  Load the JSON document from the IFS
// ----------------------------------------------------------

docNode = yajl_stmf_load_tree('pargent70.json': errMsg);
if docNode = *null;
  // TODO: handle error
endif;


// ----------------------------------------------------------
// Find the "Carriers" node in the object
// ----------------------------------------------------------

carriersNode = yajl_object_find(docNode: 'Carriers');
if carriersNode = *null;
  // Error: There was no "Carriers" node in the object.
  // TODO: Handle error
endif;


// ----------------------------------------------------------
// Load the list of carriers from the "Carriers" object
// into our data structure.
// ----------------------------------------------------------

i = 0;
count = 0;

dow YAJL_OBJECT_LOOP(carriersNode: i: key: val);

  count += 1;
  carrierList.num_carrier = count;

  CarrierList.carrier(count).name = key;
  CarrierList.carrier(count).id = grabString(val: 'CarrierID');
  CarrierList.carrier(count).service = grabString(val: 'CarrierService');

enddo;


// ----------------------------------------------------------
//  Read the validationErrors field
// ----------------------------------------------------------

carrierList.validationErrors = grabString(docNode: 'ValidationErrors');


// ----------------------------------------------------------
//  Free up YAJL resources now that everying has been
//  loaded into the DS
// ----------------------------------------------------------

yajl_tree_free(docNode);

// ----------------------------------------------------------
//  TODO: This is just to prove that the concept works.
//        Replace with "real" business logic in the
//        finished program.
// ----------------------------------------------------------

for i = 1 to carrierList.num_carrier;

  msg = carrierList.carrier(i).name
      + ' id=' + carrierList.carrier(i).id
      + ' srv=' + carrierList.carrier(i).service;

  dsply msg;

endfor;

*inlr = *on;
return;


// ----------------------------------------------------------
//   grabString(): Returns a string node from within an object
//                 or '' if the node wasn't found
//
//    obj = (input) object to locate the key in
//    keyName = (input) key ("field name") of the string
//                    within the json object ("obj")
//
//   Returns the value of the string, or '' if the string
//     was not found or wasn't a string.
// ----------------------------------------------------------

dcl-proc grabString;

  dcl-pi *n varchar(65535);
    obj     like(YAJL_VAL) value;
    keyName varchar(50) const;
  end-pi;

  dcl-s result varchar(65535) static;
  dcl-s tempNode like(YAJL_VAL) static;

  tempNode = yajl_object_find(obj: keyName);
  if tempNode = *null;
    result = '';
  else;
    result = yajl_get_string(tempNode);
  endif;

  return result;

end-proc;
pargent70
Posts: 5
Joined: Tue Aug 30, 2022 7:54 am

Re: DATA-INTO. missing nodes name

Post by pargent70 »

This is the real json that I received:

Code: Select all

{
	"Carriers": {
		"Generic": [
			{
				"CarrierID": "3103",
				"CarrierService": "Standard"
			}
		],
		"DHLParcel": [
			{
				"CarrierID": "1392",
				"CarrierService": "Paket DE"
			}
		],
		"BRT": [
			{
				"CarrierID": "3678",
				"CarrierService": "Standard"
			}
		],
		"PosteDeliveryBusiness": [
			{
				"CarrierID": "384",
				"CarrierService": "Standard"
			}
		],
		"MyDHL": [
			{
				"CarrierID": "2098",
				"CarrierService": "Standard"
			},
			{
				"CarrierID": "2099",
				"CarrierService": "Standard"
			}
		]
	},
	"ValidationErrors": ""
}
I've solved by :
YAJL_object_find(docNode: 'Carriers');
then YAJL_OBJECT_LOOP and YAJL_ARRAY_LOOP

when the CarrieID match with the carried id that I know,
I retrieve the name of the parent node.

Now I'm continuing the devolopment,
but I will comeback on your code to try to improve mine.

thanks a lot
Post Reply