The DATA-INTO opcode parses a structured document (JSON, CSV, or any format) into a
qualified data structure. It generalizes XML-INTO: where XML-INTO has a built-in XML
parser, DATA-INTO has no built-in parser - you name one with %PARSER, and it
reports the names and values it finds. RPG performs the name-to-subfield mapping using the
same rules and options as XML-INTO.
data-into receiver %data(document : options) %parser(parser : parserOptions);
receiver- the data structure to populate.%data(document : options)- the document string and the DATA-INTO options (below).%parser(parser : parserOptions)- the parser and any parser-specific options. In rpgc the parser is a bound procedure in the same module (named directly, e.g.%parser(myParser));parserOptions, when given, is passed to the parser.
The parser interface
A parser is a procedure that takes one parameter - the parser-info data structure
(QrnDiParm_T) - and reports the document's structure by calling the runtime callback
procedures. The compiler recognizes the QrnDi* callbacks by name and binds them to its
runtime, so you declare their prototypes inline (or /copy IBM's QRNDTAINTO member) and
no service program is required:
dcl-ds QrnDiParm_T qualified template;
data pointer; // pointer to the document bytes
env pointer; // reserved (the callback environment)
handle pointer; // pass as the first argument to every callback
dataLen uns(10); // document length in bytes
end-ds;
dcl-pr QrnDiStart extproc('QrnDiStart'); handle pointer value; end-pr;
dcl-pr QrnDiFinish extproc('QrnDiFinish'); handle pointer value; end-pr;
dcl-pr QrnDiStartStruct extproc('QrnDiStartStruct'); handle pointer value; end-pr;
dcl-pr QrnDiEndStruct extproc('QrnDiEndStruct'); handle pointer value; end-pr;
dcl-pr QrnDiReportNameCcsid extproc('QrnDiReportNameCcsid');
handle pointer value; name pointer value; nameLen uns(10) value; ccsid uns(10) value;
end-pr;
dcl-pr QrnDiReportValueCcsid extproc('QrnDiReportValueCcsid');
handle pointer value; val pointer value; valLen uns(10) value; ccsid uns(10) value;
end-pr;
The callbacks the compiler binds are: QrnDiStart / QrnDiFinish (bracket the parse),
QrnDiStartStruct / QrnDiEndStruct and QrnDiStartArray / QrnDiEndArray (structure
and array boundaries), QrnDiReportName / QrnDiReportValue and their ...Ccsid variants
(report a field name and its value), QrnDiReportError (abandon the parse with an error),
and QrnDiTrace (accepted as a no-op). A name pointer and length identify the reported
text. The ccsid a ...Ccsid callback reports is honored when decoding that text into the
receiver: 0 is the job CCSID (single-byte, read as-is); 1208/1209 are decoded as UTF-8;
1200/1201/13488/13489 as UTF-16/UCS-2; and 367 (US-ASCII), 819 (ISO-8859-1),
923 (ISO-8859-15), and 1252 (Windows-1252) as their respective single-byte encodings. A
reported CCSID outside this set is rejected at run time with status 00352 rather than
decoded with a guessed charset. Each callback takes the handle from the parser parameter as
its first argument.
Example
dcl-ds info qualified;
company char(10);
city char(10);
end-ds;
dcl-s doc varchar(20) inz('ignored');
dcl-s nm char(50);
dcl-s val char(50);
data-into info %data(doc : 'case=any') %parser(diParse);
// info.company = 'Acme Inc', info.city = 'Chicago'
dcl-proc diParse;
dcl-pi *n;
parm likeds(QrnDiParm_T) const;
end-pi;
QrnDiStart(parm.handle);
QrnDiStartStruct(parm.handle); // the receiver structure
nm = 'company';
QrnDiReportNameCcsid (parm.handle : %addr(nm) : %len(%trimr(nm)) : 0);
val = 'Acme Inc';
QrnDiReportValueCcsid(parm.handle : %addr(val) : %len(%trimr(val)) : 0);
nm = 'city';
QrnDiReportNameCcsid (parm.handle : %addr(nm) : %len(%trimr(nm)) : 0);
val = 'Chicago';
QrnDiReportValueCcsid(parm.handle : %addr(val) : %len(%trimr(val)) : 0);
QrnDiEndStruct(parm.handle);
QrnDiFinish(parm.handle);
end-proc;
A reported name matches a subfield using the case option (a lowercase name matches an
RPG subfield by default), and a reported value is converted to the subfield's type (so a
numeric subfield receives a numeric value). The strict allowmissing/allowextra rules
are enforced exactly as for XML-INTO.
%DATA options
The %data options parallel XML-INTO's %xml options: case (lower, upper, any,
convert), trim (all, none), allowmissing / allowextra (yes, no),
countprefix, path, doc, and ccsid. An unknown option name, a malformed token, or an
invalid value is rejected at compile time (TRN2401).
Supported: a bound-procedure parser reporting a flat qualified data structure (scalar subfields), with the
%DATAoptions above. Reporting into arrays and nested data structures, the%HANDLERarray form, anddoc=filedocuments are not supported.