Figure 1. Parsing directly into a variable from a file
D qualName DS QUALIFIED
D name 10A
D lib 10A
D copyInfo DS QUALIFIED
D from LIKEDS(qualName)
D to LIKEDS(qualName)
D toName S 10A VARYING
// Assume file cpyA.xml contains the following lines:
// <copyinfo>
// <to><name>MYFILE</name><lib>*LIBL</lib></to>
// <from name="MASTFILE" lib="CUSTLIB"></from>
// </copyinfo>
/free
// Data structure "copyInfo" has two subfields, "from"
// and "to". Each of these subfields has two subfields
// "name" and "lib".
xml-into copyInfo %XML('cpyA.xml' : 'doc=file');
// copyInfo.from .name = 'MASTFILE ' .lib = 'CUSTLIB '
// copyInfo.to .name = 'MYFILE ' .lib = '*LIBL '
// Parse the "copyinfo/to/name" information into variable
// "toName". Use the "path" option to specify the location
// of this information in the XML document.
xml-into toName %XML('cpyA.xml'
: 'doc=file path=copyinfo/to/name';
// toName = 'MYFILE'
Figure 2. Parsing directly into a variable from a string
variable
D info DS
D name 10A
D val 5I 0 DIM(2)
D xmlFragment S 1000A VARYING
D opts S 20A INZ('doc=string')
D dateVal S 10A INZ('12/25/04')
D format S 4A INZ('mdy/')
D mydate S D DATFMT(*ISO)
/free
// 1. Parsing into a data structure containing an array
xmlFragment = '<info><name>Jill</name>'
+ '<val>10</val><val>-5</val></info>';
xml-into info %XML(xmlFragment);
// info now has the value
// name = 'Jill'
// val(1) = 10
// val(2) = -5
// 2. Parsing into a date. The "fmt" XML attribute indicates the
// format of the XML date.
xmlFragment = '<mydate fmt="' + format + '">'
+ dateVal + '</mydate>';
xml-into mydate %XML(xmlFragment);
// xmlFragment = '<mydate fmt="mdy">12/25/04</mydate>'
// mydate = 2004-12-25
Figure 3. Parsing an unknown number of XML elements using
a handling procedure
// DDS for "MYFILE"
// A R PARTREC
// A ID 10P 0
// A QTY 10P 0
// A COST 7P 2
// XML data in "partData.xml"
// <parts>
// <part><qty>100</qty><id>13</id><cost>12.03</cost></part>
// <part><qty>9</qty><id>14</id><cost>3.50</cost></part>
// ...
// <part><qty>0</qty><id>254</id><cost>1.98</cost></part>
// </records>
Fmyfile o e disk
D options S 100A
D allOk S N
D partHandler PR 10I 0
D ok N
D parts LIKEREC(partrec) DIM(10) CONST
D numRecs 10U 0 VALUE
:
:
/free
// Initiating the parsing
options = 'doc=file path=parts/part';
allOk = *ON;
xml-into %HANDLER(partHandler : allOk)
%XML('partData.xml' : options);
// Check if the operation wrote the data
// successfully
if not allOk;
// some output error occurred
endif;
/end-free
:
:
// The procedure to receive the data from up to 10
// XML elements at a time. The first call to the
// this procedure would be passed the following data
// in the "parts" parameter:
// parts(1) .id = 13 .qty = 100 .cost = 12.03
// parts(2) .id = 14 .qty = 9 .cost = 3.50
// ...
// If there were more than 10 "part" child elements in
// the XML file, this procedure would be called more
// than once.
P partHandler B
D PI 10I 0
D ok 1N
D parts LIKEREC(partrec) DIM(10) CONST
D numRecs 10U 0 VALUE
D i S 10I 0
* xmlRecNum is a static variable, so it will hold its
* value across calls to this procedure.
* Note: Another way of storing this information would be to
* pass it as part of the first parameter; in that
* case the first parameter would be a data structure
* with two subfields: ok and xmlRecNum
D xmlRecNum S 10I 0 STATIC INZ(0)
/free
for i = 1 to numRecs;
xmlRecNum = xmlRecNum + 1;
write(e) partRec parts(i);
// Parameter "ok" was passed as the second parameter
// for the %HANDLER built-in function for the XML-INTO
// operation. The procedure doing the XML-INTO
// operation can check this after the operation to
// see if all the data was written successfully.
if %error;
// log information about the error
logOutputError (xmlRecNum : parts(i));
ok = *OFF;
endif;
endfor;
// continue parsing
return 0;
/end-free
P E
For more information about XML operations, see XML Operations .