utilizing an unnamed array of objects

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/
Post Reply
swofford
Posts: 2
Joined: Mon Jun 13, 2022 3:09 pm

utilizing an unnamed array of objects

Post by swofford »

I can't figure out how to specify the number of objects in this example. This is a very simplified(one element) example of what I am dealing with. This is a 3rd party API I am trying to communicate with and I need from one to three dimentioned objects in one json, but I don't want an empty object to be sent in this example. I can think of some work arounds but thought I'd check here, I just can't find anything in the documentation that addresses this nameless array scenario.

Contents of smallexample.json

Code: Select all

[
  {
     "ShipmentID": 100
  },
  {
     "ShipmentID": 200
  }
]

Code: Select all

**FREE
ctl-opt dftactgrp(*no);

readTheJson();
*inlr = *on;


dcl-proc readTheJson;

  Dcl-S num_jsonDoc int(10) inz(0);  // Modified to add Dcl-S
  dcl-ds jsonDoc qualified dim(3);
    SHIPMENTID packed(3) inz(0);
  end-ds;

  Dcl-S Request Varchar(5000);
  Dcl-S ifsPathName varchar(5000);

  ifsPathName = '/temp/smallexample.json';


  data-into jsonDoc %DATA( ifsPathname
                         : 'doc=file case=convert countprefix=num_')
                  %PARSER( 'YAJLINTO'
                         : '{ "document_name": "jsonDoc", +
                              "number_prefix": "YAJL_" }');

  DATA-GEN jsonDoc %Data( Request : 'countprefix=num_ trim=all' )
      %Gen( 'YAJLDTAGEN');

  Return;

end-proc;         
The data-into loads the data structure as expected. however the num_jsonDoc doesn't get populated
because it is not part of the data structure.
Note: I used YAGLGEN to create this program(except that I added the data-gen to demonstrate the result.

YAJLGEN created the num_jsonDoc on a line without the Dcl-S, I added that to get it to compile
In this case I want to have up to a dim of 3 of the json objects contained within the unnamed array

The DATA-GEN creates three instead of two objects because I don't know where to put the num_jsonDoc element
within the data structure.

Code: Select all

[{"SHIPMENTID":100},{"SHIPMENTID":200},{"SHIPMENTID":0}]
Any help would be much appreciated. Thanks

p.s. it looks like the yajl version is from Aug 2020. Not sure how to find the version number
Scott Klement
Site Admin
Posts: 636
Joined: Sun Jul 04, 2021 5:12 am

Re: utilizing an unnamed array of objects

Post by Scott Klement »

You can't just declare a standalone field named num_jsonDoc like that.

Think about how your code tells DATA-INTO which variable to load from the JSON document. It does this:

Code: Select all

 data-into jsonDoc . . . 
Since num_jsonDoc isn't a part of jsonDoc, it has no way to know that it's related in any way. As humans, we might say "but... it follows the naming convention that I used for count fields", but the computer doesn't understand human naming conventions.

Instead, DATA-INTO will set positions 372 - 379 of the PSDS (Program Status Data Structure) with the count of the number of elements in the outermost portion of the JSON document. In your example, the JSON document contains 2 objects (one for ShipmentID 100, and one for 200) so positions 372-379 of the PSDS would contain the number 2.

For DATA-GEN, you can control the number of elements using %SUBARR.

Here's my modified version of your program to illustrate this:

Code: Select all

**FREE
ctl-opt dftactgrp(*no);

dcl-ds myPSDS PSDS qualified;
  jsonElements int(20) pos(372);
end-ds;

readTheJson();
*inlr = *on;


dcl-proc readTheJson;

  dcl-ds jsonDoc qualified dim(3);
    SHIPMENTID packed(3) inz(0);
  end-ds;

  Dcl-S Request Varchar(5000);
  Dcl-S ifsPathName varchar(5000);
  dcl-s x int(10);

  ifsPathName = 'smallexample.json';


  data-into jsonDoc %DATA( ifsPathname
                         : 'doc=file case=convert countprefix=num_')
                  %PARSER( 'YAJLINTO'
                         : '{ "document_name": "jsonDoc", +
                              "number_prefix": "YAJL_" }');

  // You can use position 372 of the PSDS to see how many elements were loaded:

  for x = 1 to myPSDS.jsonElements;
    dsply ('ShipmentID = ' + %char(jsonDoc(x).SHIPMENTID));
  endfor;

  // For DATA-GEN use %SUBARR to control how many are output

  DATA-GEN %SubArr(jsonDoc:1:myPSDS.jsonElements)
           %Data( Request : 'countprefix=num_ trim=all' )
           %Gen( 'YAJLDTAGEN');

  Return;

end-proc;
swofford
Posts: 2
Joined: Mon Jun 13, 2022 3:09 pm

Re: utilizing an unnamed array of objects

Post by swofford »

Thank you as always Scott.

I realized how YAJLGEN created the JSON that something was wrong because it didn't have the Dcl-S on the num_jsonDoc line.
That part was really for testing anyways, in the actual program the data structure will be populated by the program.

It just never occurred to me to use the %Subarr on the data-gen. It works perfect.
Post Reply