/**
* \brief XML DOM Example
*
* Parses an XML file from the IFS and outputs all data element names and
* length from the record format elements.
*
*
*
* The XML file must have the following path and name:
* /tmp/rfml-xmldom-example.rfml
*
*
*
* The DTD to the XML file is expected at /tmp/rfml.dtd .
* The DTD can be found in the JTOpen Toolbox Jar File or at
* http://www.rpgnextgen.com/downloads/rfml.dtd .
*
*
*
* The XML Toolkit is used for parsing the string. A DOM representation of
* the XML file will be created with the Xerces XML DOM parser. For any
* further querying of the XML content the in memory XML DOM object is used.
* This provides a fast a flexible way of accessing the XML content with
* additional IO.
*
*
*
* If the XML Toolkit has been installed the documentation for the XML
* toolkit can be retrieved from the IFS at the following path:
* /QIBM/ProdData/xmltoolkit2/xml5_6_0/doc/xml4pr/index.html
*
* \author Mihael Schmidt
* \date 20.03.2009
*
* \link http://www-03.ibm.com/systems/i/software/xml/index.html XML on System i
*
*/
H dftactgrp(*no) actgrp(*caller)
H ccsid(*ucs2 : 13488)
*---------------------------------------------------------------
* PEP
*---------------------------------------------------------------
D main PR extpgm('XMLDOM01')
D main PI
*---------------------------------------------------------------
* Prototypes
*---------------------------------------------------------------
D printError PR
*
/copy QXMLDEV560/QRPGLESRC,QXML4PR560
// /copy QCPYSRC,MESSAGE
*---------------------------------------------------------------
* Constants
*---------------------------------------------------------------
Dtrue C 1
Dfalse C 0
Dnull C x'00'
*---------------------------------------------------------------
* Variables
*---------------------------------------------------------------
D rfmlFilePath S 200A
D i S 10I 0
D elementName S 100A
D dataCount S 10I 0
D attrValue S 50A
D dataLength S 10I 0
D dataName S 20A
*
* XML DOM stuff
*
D domEnvData S * INZ(%ADDR(Qxml_DOMEXCDATA))
D parser S *
D document S *
D recordFormatNodeList...
D S *
D recordFormat S *
D dataNodeList S *
D data S *
D dataAttributes S *
D attr S *
// strings are returned as unicode so we need to define a unicode variable
D xmlPtr S *
D xmlString S 200C based(xmlPtr)
/free
clear Qxml_SAXExcData;
rfmlFilePath = '/tmp/rfml-xmldom-example.rfml' + null;
// Initialize the XML environment, provide pointer to DOM exception
// data area. A call to QxmlInit must occur before any other API
// call.
QxmlInit(domEnvData);
// Create a new parser instance
parser = QxmlXercesDOMParser_new(domEnvData);
// Configure parser
QxmlXercesDOMParser_setValidationScheme(parser : Qxml_VALAU);
QxmlXercesDOMParser_setDoNamespaces(parser : true);
QxmlXercesDOMParser_setDoSchema(parser : true);
QxmlXercesDOMParser_setValidationSchemaFullChecking(parser : true);
// Parse xml file
QxmlXercesDOMParser_parse_SystemId(parser :
%addr(rfmlFilePath) :
Qxml_JOBCCSID :
0);
// Check for parse error
if (Qxml_ErrorType = Qxml_NOERROR or
Qxml_ErrorType = Qxml_WARNING);
// Get DOM document
document = QxmlXercesDOMParser_getDocument(parser);
// Get a node list with all record formats
elementName = 'recordformat' + null;
recordFormatNodeList = QxmlDOMDocument_getElementsByTagname(
document :
%addr(elementName) :
Qxml_CHARSTR :
%len(%trim(elementName)));
dsply %trimr('Number of record formats: ' +
%char(QxmlDOMNodeList_getLength(recordFormatNodeList)));
if (QxmlDOMNodeList_getLength(recordFormatNodeList) > 0);
// Get first record format
recordFormat = QxmlDOMNodeList_item(recordFormatNodeList : 0);
// Get a node list with data nodes in this record format
elementName = 'data' + null;
dataNodeList = QxmlDOMElement_getElementsByTagname(
recordFormat :
%addr(elementName) :
Qxml_CHARSTR :
%len(%trim(elementName)));
dataCount = QxmlDOMNodeList_getLength(dataNodeList);
dsply %trimr('Number of data elements: ' + %char(dataCount));
// Iterate through the data elements and display its names
for i = 0 to dataCount - 1;
data = QxmlDOMNodeList_item(dataNodeList : i);
// retrieve data node attributes
dataAttributes = QxmlDOMNode_getAttributes(data);
// Get attribute "name" value
elementName = 'name' + null;
attr = QxmlDOMNamedNodeMap_getNamedItem(dataAttributes :
%addr(elementName) :
Qxml_CHARSTR :
%len(%trim(elementName)));
xmlPtr = QxmlDOMNode_getNodeValue(attr);
// convert from unicode to ebcdic
attrValue = %char(xmlString);
dataName = %str(%addr(attrValue));
// Get attribute "length" value
elementName = 'length';
attr = QxmlDOMNamedNodeMap_getNamedItem(dataAttributes :
%addr(elementName) :
Qxml_CHARSTR :
%len(%trim(elementName)));
xmlPtr = QxmlDOMNode_getNodeValue(attr);
// convert from unicode to ebcdic
attrValue = %char(xmlString);
dataLength = %int(%str(%addr(attrValue)));
// output data node name and length
dsply %trimr('Node ' + %trimr(dataName) + ': ' +
%char(dataLength));
endfor;
else;
dsply 'No record formats in this rfml file.';
endif;
else;
printError();
endif;
QxmlTerm();
*inlr = *on;
return;
/end-free
/**
* \brief Print last XML error
*
* Prints the last XML error to with the error position in the XML file
* to the job log.
*
* \todo make MESSAGE service program available
*/
P printError B
D PI
/free
// sends a message to the job log
// msg_sendProgramMessage('An error occured at line ' + %char(Qxml_RtnLine)+
// ' column ' + %char(Qxml_RtnCol) + '. Error: ' +
// %trimr(Qxml_ErrMsg : ' ' + x'00'));
dsply %trimr('XML error at %char(Qxml_RtnLine) + '/' +
%char(Qxml_RtnCol) + '.');
/end-free
P E