I'm new to YAJLINTO and working with JSON so please go easy on me

Doesn't help that my first attempt is with a (I think) complex JSON!
Below is a an example of the JSON response I am trying to parse. It's returned from an API call to retrieve a set of exchange rates on a given date, and the only data I am interested in is the 10 elements shown in red within the NAVEXRATELIST.Results array.
{
"d" : {
"results": [{
"__MetaData": {
"id": "https:sakjdskaljdklaskljsanndksadklsajdsjadjsadjsa=dsadshjkadsa=dsahkj",
"uri" : "hjkhkjhkjhkjhkjhjhjhjhkjhjkhhkjhjk",
"type": "exchange-rates.ExchRateList"},
"field1": "",
"InputDate": "",
"DateType": "",
"RateType": "",
"CurrFrom": "",
"CurrTo": "",
"ShowProtocol": false,
"NAVRETURN": {
"results": []
},
"NAVEXCRATELIST" : {
"Results" : [
{
"__MetaData": {
"id": "https:sakjdskaljdklaskljsanndksadklsajdsjadjsadjsa=dsadshjkadsa=dsahkj",
"uri" : "hjkhkjhkjhkjhkjhjhjhjhkjhjkhhkjhjk",
"type": "exchange-rates.ExchRateList"},
"RateType": "001A",
"FromCurr": "AAA",
"ToCurrncy": "BBB",
"ValidFrom": "/Date(1682812800000)/",
"ExchRate": "24.94164",
"FromFactor": "100",
"ToFactor": "1",
"ExchRateV": "0.00000",
"FromFactorV": "0",
"ToFactorV": "0"
},
{
"__MetaData": {
"id": "https:sakjdskaljdklaskljsanndksadklsajdsjadjsadjsa=dsadshjkadsa=dsahkj",
"uri" : "hjkhkjhkjhkjhkjhjhjhjhkjhjkhhkjhjk",
"type": "exchange-rates.ExchRateList"},
"RateType": "001A",
"FromCurr": "CCC",
"ToCurrncy": "DDD",
"ValidFrom": "/Date(1682812800000)/",
"ExchRate": "24.94164",
"FromFactor": "100",
"ToFactor": "1",
"ExchRateV": "0.00000",
"FromFactorV": "0",
"ToFactorV": "0"
},
{
"__MetaData": {
"id": "https:sakjdskaljdklaskljsanndksadklsajdsjadjsadjsa=dsadshjkadsa=dsahkj",
"uri" : "hjkhkjhkjhkjhkjhjhjhjhkjhjkhhkjhjk",
"type": "exchange-rates.ExchRateList"},
"RateType": "001A",
"FromCurr": "EEE",
"ToCurrncy": "FFF",
"ValidFrom": "/Date(1682812800000)/",
"ExchRate": "24.94164",
"FromFactor": "100",
"ToFactor": "1",
"ExchRateV": "0.00000",
"FromFactorV": "0",
"ToFactorV": "0"
}
]
}
}
]
}
It took me longer than I care to admit to get my data structures defined to handle this, but it is now working and the data is being parsed.
However, my issue is with the array size.
Here is my code:
Code: Select all
// Data structure to hold the 10 exchange rate items (I'm just throwing everything into VarChar for now)
Dcl-ds ExRateItem Qualified;
RateType VarChar(4);
FromCurr VarChar(3);
ToCurrncy VarChar(3);
ValidFrom VarChar (25);
ExchRate VarChar (13);
FromFactor VarChar (3);
ToFactor VarChar (3);
ExchRateV VarChar (13);
FromFactorV VarChar (13);
ToFactorV VarChar (3);
End-Ds;
//Data Structure for the List of Exchange Rates, i.e. the array I am interested in
Dcl-Ds ExRateList Qualified;
results LikeDS(ExRateItem) DIM(450);
End-Ds;
//Data Structure for the NAVEXCRATELIST object
Dcl-Ds ListSet Qualified;
NAVEXCRATELIST LikeDS(ExRateList);
End-Ds;
//Data Structure for the 'Main Result' object
Dcl-Ds MainResult Qualified;
results LikeDS(ListSet) DIM(1); //(there will only ever be 1 "main" result)
End-Ds;
//Final Data Structure for the root object itself
Dcl-Ds Root Qualified;
d LikeDS(MainResult);
End-ds;
// Parse the JSON. allowextra=yes means I don't need to define data structures for everything.
data-into Root
%data(%trim(ifsfile)
: 'doc=file case=any allowextra=yes allowmissing=yes')
%parser('YAJLINTO') ;
// Quick loop just to count how many sets of exchange rates I loaded
itemCount = 0;
for i = 1 to %elem(Root.D.results(1).NAVEXCRATELIST.results);
if Root.D.results(1).NAVEXCRATELIST.results(i).FromCurr <> ' ';
itemCount +=1 ;
endif;
endfor;
Because my test data just has 3 sets of rates the parse failed as it 'expects' 450, and likewise trying to parse a real file (357 sets) failed for the same reason.
As soon as I added "allowmissing=yes" the parse was fine.
The problem is I have no idea how many sets of data I actually loaded. As soon as my count loop (i) exceeds the number of items it actually found my program fails with "Length of varying length variable is out of range", so using this test data it correctly loops 3 times and itemCount = 3, but on the 4th loop it fails because there is no 4th+ array element data. Likewise using a real file, it loops 357 times but then fails on loop 358.
I have seen some comments about using countprefix_ but I'm struggling to figure out exactly where to code that. I did try it in a few places but the count was nowhere near what it should be (e.g. when parsing the real file with 357 items the count came back at 64?), and furthermore the array always ended up empty anyway.
Of course I will be doing more on each iteration of the loop, not just counting (I will be reformatting each data item (if required) and writing to an externally described physical file, I've just put this quick count loop in place to get the basic program structure in place.
Hope this makes sense.
Many thanks.