Skip to content

DATA INTO and DATA GEN

Daniel Long edited this page Sep 29, 2026 · 3 revisions

DATA-INTO and DATA-GEN

DATA-INTO parses structured data into a data structure. DATA-GEN serializes a data structure to structured data.

The third operand names the handler, as IBM i requires: %PARSER for DATA-INTO (RNF5449 without it) and %GEN for DATA-GEN (RNF5454). On IBM i the name is a program that parses or generates the document. OpenRPG has two built in: a name containing CSV selects comma-separated values, and any other name, such as 'JSON', selects JSON.

DATA-INTO ds %DATA(source : 'options') %PARSER('JSON' : 'parser options');
DATA-GEN  ds %DATA(target : 'options') %GEN('JSON' : 'generator options');

%DATA's options are IBM's, and a literal is checked when the program compiles (RNF0236). DATA-INTO takes doc, case, trim, allowmissing, allowextra, path, ccsid and countprefix. DATA-GEN takes doc, countprefix, renameprefix, output and name. Options for the handler itself, like the CSV handler's header and delimiter, go in the second operand of %PARSER or %GEN.

DATA-INTO — Parse JSON

DCL-DS person QUALIFIED;
  name VARCHAR(40);
  age  INT(10);
  city VARCHAR(30);
END-DS;

DCL-S json VARCHAR(500);
json = '{"name":"Alice","age":30,"city":"Boston"}';

DATA-INTO person %DATA(json : 'doc=string case=any') %PARSER('JSON');

DSPLY person.name;              // Alice
DSPLY %CHAR(person.age);        // 30
DSPLY person.city;              // Boston

The %DATA BIF takes the data source and an options string:

Option Meaning
doc=string The data is a string variable (not a file)
case=any Case-insensitive field name matching

Fields not present in the JSON default to zero (numeric) or blank (character).

DATA-GEN — Generate JSON

DCL-DS item QUALIFIED;
  id    INT(10);
  price PACKED(9:2);
  label VARCHAR(30);
END-DS;

DCL-S json VARCHAR(300);
DCL-S dspLine VARCHAR(52);   // DSPLY shows at most 52 characters

item.id    = 42;
item.price = 19.99;
item.label = 'Widget';

DATA-GEN item %DATA(json : 'doc=string') %GEN('JSON');

dspLine = json;
DSPLY dspLine;   // {"id":42,"price":19.99,"label":"Widget"}

Numeric Types

PACKED, ZONED, INT, FLOAT, and UNS fields all round-trip correctly:

DCL-DS product QUALIFIED;
  id    INT(10);
  price PACKED(9:2);
  qty   INT(10);
END-DS;

json = '{"id":99,"price":4.50,"qty":10}';
DATA-INTO product %DATA(json : 'doc=string case=any') %PARSER('JSON');

DSPLY %CHAR(product.price);   // 4.50

Special Characters in Strings

DATA-GEN escapes double-quotes and other JSON special characters automatically:

DCL-DS msg QUALIFIED;
  text VARCHAR(100);
END-DS;

msg.text = 'Price < $10 & "sale"';
DATA-GEN msg %DATA(json : 'doc=string') %GEN('JSON');
// {"text":"Price < $10 & \"sale\""}

CSV Format via %PARSER('CSV') and %GEN('CSV')

Use %PARSER('CSV') to parse and %GEN('CSV') to generate comma-separated values. The first row is treated as a header row mapping column names to DS field names.

DATA-INTO — Parse CSV

DCL-DS person QUALIFIED;
  name VARCHAR(40);
  age  INT(10);
  city VARCHAR(30);
END-DS;

DCL-S csv VARCHAR(500);
csv = 'NAME,AGE,CITY' + X'0A' + 'Alice,30,Boston';

DATA-INTO person %DATA(csv : 'case=any') %PARSER('CSV');

DSPLY person.name;   // Alice
DSPLY %CHAR(person.age);   // 30

For array DS, each data row maps to one element:

DCL-DS emp DIM(*VAR:10) QUALIFIED;
  name VARCHAR(40);
  dept VARCHAR(20);
END-DS;

DCL-S csv VARCHAR(500);
csv = 'NAME,DEPT' + X'0A' + 'Bob,Engineering' + X'0A' + 'Carol,Marketing';

DATA-INTO emp %DATA(csv : 'case=any') %PARSER('CSV');
// %ELEM(emp) = 2

DATA-GEN — Generate CSV

DCL-DS person QUALIFIED;
  name VARCHAR(40);
  age  INT(10);
END-DS;

DCL-S csv VARCHAR(300);
person.name = 'Alice';
person.age  = 30;

DATA-GEN person %DATA(csv) %GEN('CSV');
// csv = "NAME,AGE\nAlice,30"

CSV Options

Option Where Meaning
case=any %DATA (DATA-INTO) Case-insensitive header matching
header=no %PARSER / %GEN Skip header row on input / omit header row on output
delimiter=<c> %PARSER / %GEN Use <c> as field delimiter instead of comma
DATA-GEN person %DATA(csv) %GEN('CSV' : 'header=no delimiter=;');

Hex String Literals (X'...')

RPG does not have string escape sequences. Use hex literals to embed control characters such as newline (X'0A') or carriage-return (X'0D') in strings:

DCL-C LF X'0A';
csv = 'NAME,AGE' + LF + 'Alice,30';

Clone this wiki locally