EXPARSE1
This example program demonstrates the basic structure of an RPG program utilizing RPG-XML Suite to parse JSON data.
H DFTACTGRP(*NO) ACTGRP(*CALLER) BNDDIR('RXSBND')
/copy QRPGLECPY,RXSCB
D JSONHandler PR N
D pType 5I 0 Const
D pPath Const Like(RXS_Var64Kv_t)
D pIndex 10U 0 Const
D pData * Const
D pDataLen 10U 0 Const
D Json S Like(RXS_Var64Kv_t)
D ParseJsonDS DS LikeDS(RXS_ParseJsonDS_t)
/FREE
Json = '{ "glossary": { "title":'
+ ' "example glossary", "GlossDiv": { "title": "S", "'
+ 'GlossList": [ { "ID": "SGML", "SortAs": "SGML", "'
+ 'GlossTerm": "Standard Generalized Markup Language", "Ac'
+ 'ronym": "SGML", "Abbrev": "ISO 8879:1986", "GlossDe'
+ 'f": "A meta-markup language, used to create markup langua'
+ 'ges such as DocBook.", "GlossSeeAlso": ["GML", "XML"'
+ ', "markup", "test"] } ] } } }';
monitor;
// Use RXS_ResetDS to ensure that RXS templated data structures are
// properly configured before use
RXS_ResetDS( ParseJsonDS : RXS_DS_TYPE_PARSEJSON );
// The JSON parsing in RXS functions via an "event-based" method.
// Basically, you will create a "handler" subprocedure that will
// be called by RXS_ParseJson once for each "event" detected in
// the JSON being parsed. An event is one of the following:
// - beginning of an JSON Array (RXS_JSON_ARRAY_BEGIN)
// - end of an JSON Array (RXS_JSON_ARRAY_END)
// - beginning of an JSON Object (RXS_JSON_OBJECT_BEGIN)
// - end of an JSON Object (RXS_JSON_OBJECT_END)
// - a JSON string value (RXS_JSON_STRING)
// - a JSON integer value (RXS_JSON_INTEGER)
// - a JSON double (float) value (RXS_JSON_DOUBLE)
// - a JSON boolean (indicator) value (RXS_JSON_BOOLEAN)
// - a JSON null value (RXS_JSON_NULL)
// Inside the "handler" subprocedure (named JSONHandler here), you
// will receive a number of parameters that describe the data
// associated with the event detected. JSONHandler() explains this
// in more detail
ParseJsonDS.Handler = %Paddr( JSONHandler );
RXS_ParseJson( Json : ParseJsonDS );
on-error;
endmon;
*INLR = *ON;
return;
/END-FREE
P JSONHandler B Export
D PI N
D pType 5I 0 Const
D pPath Const Like(RXS_Var64Kv_t)
D pIndex 10U 0 Const
D pData * Const
D pDataLen 10U 0 Const
*
D ParsedData S Like(RXS_Var1Kv_t)
/FREE
// JSONHandler must always be specified with the exact same prototype
// - the same number of parameters, the same number of field types, in
// the same order, etc. The parameters are:
//
// - pType = the event type, e.g. RXS_JSON_STRING, RXS_JSON_ARRAY_BEGIN,
// etc.
// - pPath = XPath like syntax that indicates where in the JSON
// structure being parsed we are located. You can "drill down" with
// slashes (e.g. /object1/field1 corresponds to a 'field1' inside
// a parent object named 'object1', and you can indicate when a JSON
// JSON Array is present via [*] - further explanation below.
// -pIndex = If the JSON object/event we're handling is a child of a
// JSON Array, this will indicate the 'index", e.g. the position of
// this object within the array, starting from a value of 1. This
// parameter is not relevant for objects/events noSt inside an array
// -pData = Pointer to the actual data returned. This will only be set
// for RXS_JSON_STRING, RXS_JSON_INTEGER, RXS_JSON_DOUBLE, and
// RXS_JSON_BOOLEAN. It is technically also set for RXS_JSON_NULL,
// but will be an RPG *Null value. For RXS_JSON_OBJECT,
// RXS_JSON_OBJECT_END, RXS_JSON_ARRAY, and RXS_JSON_ARRAY_END,
// this will also be *Null as there isn't any data associated with
// these events.
// -pDataLen = Length of the object. Typically this is used as the
// length of pData as a call to RXS_STR() as seen below, but pDataLen
// is also set to either the total length of a JSON Array or the
// number of "first tier" fields in a JSON Object
// We're going to grab the content of the JSON object that was passed
// to JSONHandler, assuming that the object HAS content, e.g. it is
// a string, integer, double, or boolean.
if pData <> *Null and pDataLen > 0;
ParsedData = RXS_STR( pData : pDataLen );
endif;
select;
// For JSON parsing with RXS, a [*] being part of the path indicates
// that an array is involved. If you need to know the specific
// position in the array you can look at the pIndex value. Note that
// for nested arrays pIndex will show the position of the deepest
// JSON Array in the path.
when pPath = '/';
RXS_JobLog( 'Root object (length %s)' : %Char(pDataLen) );
when pPath = '/glossary';
RXS_JobLog( 'glossary object (length %s)' : %Char(pDataLen) );
when pPath = '/glossary/title';
RXS_JobLog( 'glossary title: %s' : ParsedData );
when pPath = '/glossary/GlossDiv/title';
RXS_JobLog( 'GlossDiv title: %s' : ParsedData );
when pPath = '/glossary/GlossDiv/GlossList[*]';
if pType = RXS_JSON_ARRAY;
RXS_JobLog( 'Begin GlossList Array (length %s)'
: %Char(pDataLen) );
elseif pType = RXS_JSON_ARRAY_END;
RXS_JobLog( 'End GlossList Array (length %s)'
: %Char(pDataLen) );
endif;
when pPath = '/glossary/GlossDiv/GlossList[*]/ID';
RXS_JobLog( 'GlossList Array#%s ID: %s'
: %Char(pIndex) : ParsedData );
when pPath = '/glossary/GlossDiv/GlossList[*]/SortAs';
RXS_JobLog( 'GlossList Array#%s SortAs: %s'
: %Char(pIndex) : ParsedData );
when pPath = '/glossary/GlossDiv/GlossList[*]/GlossTerm';
RXS_JobLog( 'GlossList Array#%s GlossTerm: %s'
: %Char(pIndex) : ParsedData );
when pPath = '/glossary/GlossDiv/GlossList[*]/Acronym';
RXS_JobLog( 'GlossList Array#%s Acronym: %s'
: %Char(pIndex) : ParsedData );
when pPath = '/glossary/GlossDiv/GlossList[*]/Abbrev';
RXS_JobLog( 'GlossList Array#%s Abbrev: %s'
: %Char(pIndex) : ParsedData );
when pPath = '/glossary/GlossDiv/GlossList[*]/GlossDef';
RXS_JobLog( 'GlossList Array#%s GlossDef: %s'
: %Char(pIndex) : ParsedData );
when pPath = '/glossary/GlossDiv/GlossList[*]/GlossSeeAlso[*]';
if pType = RXS_JSON_ARRAY;
RXS_JobLog( 'Begin GlossSeeAlso Array (length %s)'
: %Char(pDataLen) );
elseif pType = RXS_JSON_ARRAY_END;
RXS_JobLog( 'End GlossSeeAlso Array (length %s)'
: %Char(pDataLen) );
else;
RXS_JobLog( 'GlossSeeAlso Array#%s value: %s'
: %Char(pIndex) : ParsedData );
endif;
endsl;
// If you want to stop parsing early for whatever reason, return
// RXS_JSON_STOP_PARSING
return RXS_JSON_CONTINUE_PARSING;
/END-FREE
P E