Thanks Scott!

I’ll string them together. My use case in this instance is simple, but it could get more complicated quickly. I had not considered international issues until now either.

The sub procedure method might get me past some of the PTF (or lack thereof) issues we face.

I started with RPG on a S/3 so I fit into that “old” category but doing the things younger programmers would understand better makes sense. The other reason would be if we mix RPG with Python, something one of my developers want to do.

Jim Oberholtzer
Agile Technology Architects

On Oct 14, 2021, at 12:45 PM, Scott Klement <rpg400-l@xxxxxxxxxxxxxxxx> wrote:

Hi Jim,

It *could* be a data structure -- if that works for the document you're trying to make. The problem with a data structure is that the data would need to be in fixed positions, which is not typically what you want in a JSON document. If it works for your particular document, I guess more power to you?

For example, suppose I'm creating this document:

{"custno": 5,"name": "Jim Oberholtzer"}

Your suggestion is to make a data structure, and I assume you mean something like this:

dcl-ds data qualified;
*n char(10) inz('{"custno":');
custno zoned(1: 0);
*n char(9) inz(',"name":"');
name char(15);
*n char(2) inz('"}');

data.custno = 5; = 'Jim Oberholtzer';

Note that data structures in RPG can be used as strings, so you can pass 'data' to the QtmhWrStout() subprocedure without any problems, since it can be treated as a character string.

But, is it a good idea? Uhhh... as long as the customer number is always 1 digit long and the customer's name is always 15 characters long. If you had a longer customer number, then you'd have to make the 'custno' field larger, and then you'd end up with leading zeroes in the JSON document, which has the potential to cause problems.

Likewise, if the customer name was shorter than 15, you'd end up with extra blanks in the name. If it was longer than 15, it wouldn't fit -- you'd have to expand the name field, which would require even more extra trailing blanks in the name for shorter names.

Data structures really only work for things where the data goes in fixed positions, not where it needs to be in different positions based on the length of the preceding data.

By contrast, if you did this:

*data = '{"custno":' + %char(custno) + ',"name":"' + %trim(name) + '"}';*

Then there'd never be a problem... things will shift to the right positions, etc, all will work well.

I also find the string expression easier to understand than the data structure approach -- but of course, that's a "beauty is in the eye of the beholder" type scenario -- everyone will have a different opinion. In my experience, old-school RPGers (those that came from an RPG/400 background, or earlier) are very used to the data structure approach, but younger programmers are more familiar with string expressions.

Then, you have the problem of making code that works across multiple flavors of EBCDIC. The example you posted uses %char(LBRACE) and similar things, and the reason you'd do that is for internationalization. The brace/bracket characters have a different code point in different flavors of EBCDIC. So both the data structure and string approach that I provided, above, won't work in Germany, Italy, Spain, etc (for example) if they were compiled in the USA or vice-versa. The %char(LBRACE) approach fixes that problem. But, you could do the same thing with the data structure approach if you wanted to -- its just harder to do since you're limited in what sort of expressions you can use in an INZ() keyword.

Also, neither example tries to escape any needed characters. For example if the double-quote character were in someone's name (Something like 'Scott "Darkbagel" Klement') would be problematic since they aren't escaped. But, again, this would be a similar problem with either the string or data structure approaches.

Stuff like this is why it's much nicer to use a tool like YAJL -- even if you have to call the subprocedure version instead of DATA-GEN -- because it handles all the internationalization and escaping for you.


On 10/14/2021 11:15 AM, Jim Oberholtzer wrote:
So, Back to the original question, can that be a data structure?

Jim Oberholtzer
Chief Technical Architect
Agile Technology Architects

On Thu, Oct 14, 2021 at 10:49 AM Brad Stone<bvstone@xxxxxxxxx> wrote:

Ahh.. gotcha. Ya, I don't think YAJL goes back that far. I have similar
customers.. Some even buy a "new to them box" with V7R1... *SMH*

On Thu, Oct 14, 2021 at 9:29 AM Jim Oberholtzer <

Thanks Brad, I do use YAJL where I can, unfortunately some of my
don't keep up with PTFs, or Version/Release so I have to build one
that is lacking. DATA-INTO etc are out for now at least in one version.

Maybe a better question is will YAJL go back to V5R4? I think V6R1 was
oldest Scott set it up for.

Jim Oberholtzer
Chief Technical Architect
Agile Technology Architects

On Thu, Oct 14, 2021 at 9:12 AM Brad Stone<bvstone@xxxxxxxxx> wrote:

I wouldn't build JSON from scratch... instead I'd use YAJL to build it.
there are built newer functions where you can actually use data
to build the JSON I believe. (I only use YAJL and build JSON that
YAJL also does include a function to take that JSON you just built and
write it to StdOut. Here's an example:

On Thu, Oct 14, 2021 at 9:05 AM Jim Oberholtzer <

In example of how to use QtemWrStout Scott Klement builds the
jsonName = %scanrpl( '"': '\"': );
jsonDate = %char( %date( *iso ): *iso );
data = %char(LBRACE) + CRLF
+ ' "invno": "' + row.inv + '",' + CRLF
+ ' "date": "' + jsonDate + '",' + CRLF
+ ' "name": "' + %trim(jsonName) + '",' + CRLF
+ ' "amount": "' + %char(row.amount) + '",' + CRLF
+ ' "weight": "' + %char(row.weight) + '"' + CRLF
+ %char(RBRACE);
QtmhWrStout(data: %len(data): err);

Simple enough, but can the "data" variable be a data structure
The idea being that all the constants are defined in the data
then to fill in the actual data the only need would be to be assigned
a database read or input variable.

Jim Oberholtzer
Chief Technical Architect
Agile Technology Architects

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,
or email: RPG400-L-request@xxxxxxxxxxxxxxxxxx
Before posting, please take a moment to review the archives

Please contact support@xxxxxxxxxxxxxxxxxxxx for any subscription related questions.

Help support by shopping at with our affiliate link:

As an Amazon Associate we earn from qualifying purchases.

This thread ...


Follow On AppleNews
Return to Archive home page | Return to MIDRANGE.COM home page

This mailing list archive is Copyright 1997-2021 by and David Gibbs as a compilation work. Use of the archive is restricted to research of a business or technical nature. Any other uses are prohibited. Full details are available on our policy page. If you have questions about this, please contact [javascript protected email address].

Operating expenses for this site are earned using the Amazon Associate program and Google Adsense.