Scott,
Thanks so much for taking the time to provide the suggestions and for the detailed explanation. You're right, I was extremely frustrated. I'm disappointed IBM chose to overlook unnamed elements! I have very little experience with JSON and yet I've seen this before.
Thanks again.
Greg
-----Original Message-----
From: RPG400-L [mailto:rpg400-l-bounces@xxxxxxxxxxxxxxxxxx] On Behalf Of Scott Klement
Sent: Friday, June 07, 2019 6:00 PM
To: rpg400-l@xxxxxxxxxxxxxxxxxx
Subject: Re: Help Data-Into (YAJLINTO) RPG Variable error
Hi Greg,
Thanks for providing some more details, that helped.
I'll approach this answer two ways: (1) will be to use the 'path'
option to only get the 'value' subfield from the json document. (2) will be to get the whole document and deal with the fields like @odata.context and @odata.nextLink.
FIRST SOLUTION (USING PATH):
One difference between XML and JSON is that the document element (the one that surrounds all other content in the document) in JSON does not have a name. This is not unique to JSON, by the way, there are lots of formats that don't give names to internal elements.
Unfortunately, IBM didn't consider this possibility when they created DATA-INTO. I'm guessing they pretty much copied XML-INTO. For this reason, the "path=" option in data-into does not understand an unnamed elements, which IMHO, is its biggest problem.
YAJLINTO works around this by giving you the option to assign a name to the document element. It won't be assigned in the document itself, but YAJLINTO will trick data-into into thinking it is if you tell it to. This is done by passing a small JSON document to the %PARSER BIF to tell it the name of the document element.
%parser('YAJLINTO': '{ "document_name": "doc"}');
With this option, the outermost element (aka the document element) is now named "doc", so you can use a path like this: 'path=doc/value'
Using that solution results in code like this:
dcl-c RPGOPTS const('doc=file case=convert allowextra=yes path=doc/value'); dcl-c YAJLOPTS const('{ "document_name": "doc" }');
dcl-ds *n psds;
count int(20) pos(372);
end-ds;
dcl-ds Orders dim(20) qualified;
ID char(10);
ProfileID char(10);
SiteID char(15);
SiteName char(50);
SiteAccountID char(10);
SiteOrderID char(128);
// + more stuff
end-ds;
dcl-s i int(10);
Data-Into Orders %data('orders_test.json' : RPGOPTS )
%parser('YAJLINTO' : YAJLOPTS);
for i = 1 to count;
dsply orders(i).ID;
endfor;
SECOND SOLUTION (READ ENTIRE DOCUMENT)
As far as I can tell the only thing giving you trouble with reading the whole document is that you don't know how to define things that match json fields that have names that aren't allowed in RPG. DATA-INTO (as well as XML-INTO) provide an option called "case=convert" for exactly that reason. You can read how this option works here:
https://www.ibm.com/support/knowledgecenter/ssw_ibm_i_74/rzasd/caseopt.htm
In the example of @odata.context anything not A-Z or 0-9 will be translated to underscores, so you'll have '_odata_context', and then because you can't start a variable with an underscore, RPG will remove the leading underscore resulting in 'odata_context'. So if you want to use that field in your program, just use case=convert, and name the field 'odata_context'
dcl-c RPGOPTS const('doc=file case=convert allowextra=yes +
countprefix=count_');
dcl-ds json qualified;
odata_context varchar(128);
count_value int(10);
dcl-ds value dim(20);
ID char(10);
ProfileID char(10);
SiteID char(15);
SiteName char(50);
SiteAccountID char(10);
SiteOrderID char(128);
// + more stuff
end-ds;
odata_nextlink varchar(128);
end-ds;
dcl-s i int(10);
Data-Into json %data('orders_test.json' : RPGOPTS )
%parser('YAJLINTO');
for i = 1 to json.count_value;
dsply json.value(i).ID;
endfor;
I can name at least 4 ways that XML is more complicated than JSON... but, I think your statement that XML is easier is only based on you being frustrated with the PATH thing, so I'll spare you.
-SK
On 6/7/2019 4:06 PM, Greg Wilburn wrote:
Yes... I see exactly what you're saying.
But I can't have a field named "@odata.context" and "value" seems like an "envelope" around all of the data. There is another "@odata.next" at the end of value object. The actual structure for each individual order object doesn't seem to have a "name".
--
This is the RPG programming on IBM i (RPG400-L) mailing list To post a message email: RPG400-L@xxxxxxxxxxxxxxxxxx To subscribe, unsubscribe, or change list options,
visit:
https://lists.midrange.com/mailman/listinfo/rpg400-l
or email: RPG400-L-request@xxxxxxxxxxxxxxxxxx
Before posting, please take a moment to review the archives at
https://archive.midrange.com/rpg400-l.
Please contact support@xxxxxxxxxxxx for any subscription related questions.
Help support midrange.com by shopping at amazon.com with our affiliate link:
https://amazon.midrange.com
As an Amazon Associate we earn from qualifying purchases.