* * (C) Copyright IBM Corp. 2000 All rights reserved. * * US Government Users Restricted Rights Use, duplication or * disclosure restricted by GSA ADP Schedule Contract with IBM Corp. * * The program is provided "as is" without any warranty express or * implied, including the warranty of non-infringement and the implied * warranties of merchantibility and fitness for a particular purpose. * IBM will not be liable for any damages suffered by you as a result * of using the Program. In no event will IBM be liable for any * special, indirect or consequential damages or lost profits even if * IBM has been advised of the possibility of their occurrence. IBM * will not be liable for any third party claims against you. * ==================================================================== * * NOTE, modification of this file is required to input an XML file name * also change SETDOVAL arg to 0 if no dtd * or you don't want to validate * FQPRINT O F 132 PRINTER *copy the prototypes for the C++ parser procedures /COPY XML4PR310/QRPGLESRC,QXML4PR310 *copy the prototypes for the vector procedures /COPY XML4PR310/QRPGLESRC,VECTORH * DXmlFile S 90A INZ('/xml4pr310/AddressBook5.xml') * number of levels in the document to ignore (AddressBook & AddressEntry Dlevel s 5u 0 inz(2) * Pointers * DXmlFile@ S * DENVDATA@ S * INZ(%ADDR(Qxml_DOMEXCDATA)) DPRSDATA@ S * INZ(%ADDR(Qxml_SAXExcData)) * DomParse@ passed to DDomParse@ S * * DomDoc@ pointer to DOM document DDomDoc@ S * DDomNodeList@ S * DNodLstPtr@ S * DChlNodLst@ S * DDOMString@ S * DDomstrptr@ S * DNodeptr@ S * DNodemapptr@ S * DGetTagOpt@ S * Dstrgbuf@ S * Dindex S 10U 0 Delement S 15a DparentElem S 15a DchildElem S 15a DattrElem S 15a DchildVal S 15a DattrVal S 15a DhostVal S 15a DelemCount S 10I 0 INZ(0) Dtrue S 5u 0 inz(1) Dfalse S 5u 0 inz(0) Dstop S 5u 0 inz(0) Di S 5u 0 inz(0) Dj S 5u 0 inz(0) Dk S 5u 0 inz(0) Dv S 5u 0 inz(0) Dfirst S 5u 0 inz(1) DbigLongStr S 50A INZ(' ') dphoneType S 4a inz(' ') dnumAttr S 5u 0 inz(0) dvalueLen S 5u 0 inz(0) dchild S 10u 0 inz(0) DMAPSTRUCT DS DHXMLPATH 50A INZ(' ') DHVALUE 9B 0 DADENTRY DS D HFNAME 10a inz('* ') D HMNAME 10a inz('* ') D HLNAME 10A INZ('* ') D HTITLE 5A INZ('* ') D HADDTYPE 4A INZ('* ') D HSTREET 15A INZ('* ') D HCITY 15A INZ('* ') D HSTATE 2A INZ('* ') D HPOSTALC 5A INZ('* ') D HCOUNTRY 3A INZ('* ') DHEMAIL 15A INZ('* ') DHHPHONE 12A INZ('* ') DHWPHONE 12A INZ('* ') * Allocate local string areas C ALLOC 10 GetTagOpt@ C ALLOC 256 XmlFile@ C ALLOC 256 DomString@ C ALLOC 256 strgbuf@ * Move input to string areas C EVAL %str(XmlFile@:256) = %TRIMR(XmlFile) C EVAL %str(GetTagOpt@:256)='*' * Initialize XML environement, provide pointer to DOM exception area C CALLP QxmlInit(ENVDATA@) * Create a Parser object, set validation options and parse C EVAL DomParse@ = QxmlDOMParser_new(PRSDATA@) * Validate document arg - set to 1 if DTD available * and you want to use it C CALLP QxmlDOMParser_setDoValidation(DomParse@ : 0) C CALLP QxmlDOMParser_parse_SystemId(DomParse@: C XmlFile@:Qxml_CCSID37:0) * Get parse document C EVAL DomDoc@ = QxmlDOMParser_getDocument C (DomParse@) * Get a node list of all ('*') elements by tag name C EVAL DomNodeList@ = C QxmlDOM_Document_getElementsByTagName C (DomDoc@:GetTagOpt@: C Qxml_CHARSTR:1) * Get number of elements C EVAL elemCount = QxmlDOM_NodeList_getLength C (DomNodeList@) c IF elemCount > 0 * Process all of the elements c DOW i < elemCount * Retrieve the DomNode by the index C EVAL NodLstPtr@ = QxmlDOM_NodeList_item C (DomNodeList@:i) * Get the node name C EVAL Domstrptr@ = QxmlDOM_Node_getNodeName C (nodlstptr@) C EVAL element = %str( C QxmlDOMString_transcode(Domstrptr@)) C CALLP QxmlDOMString_delete(Domstrptr@) * c* Step 1 Build parentage for an element ************************************************************** * * If there are no entries in the vector c EVAL empty = ISEMPTY c IF empty =true * Place node name into vector C CALLP AddElem(element) c ELSE c EVAL stop = false c DOW stop = false * Get the parent node and parent name for the current node C EVAL Nodeptr@ = QxmlDOM_Node_getParentNode C (NodLstPtr@) C EVAL Domstrptr@ = QxmlDOM_Node_getNodeName C (Nodeptr@) C EVAL parentElem = %str( C QxmlDOMString_transcode(Domstrptr@)) C CALLP QxmlDOM_Node_delete(NodePtr@) C CALLP QxmlDOMString_delete(domstrptr@) * If parent node name same as last value in vector * add the element to the vector c IF parentElem = GetLstElem c CALLP addElem(element) c EVAL stop=true c ELSE * else, remove last element and loop until parent node is the same * or vector is empty c CALLP RemLstElem c ENDIF c IF isEmpty = true c CALLP AddElem(element) c EVAL stop = true c ENDIF c ENDDO c ENDIF * * Step 2 Determine if new entry (addressbook entry) in table c IF element = 'AddressEntry' c IF first = false C EXSR Insert c EXSR InsertStar c ELSE c EVAL first = false c ENDIF c ENDIF * * Step 3 Build the key to the MAPADDRESS table * bigLongString contains all elements from * vector less the levels to ignore c IF level < NumElem C EVAL bigLongStr = GetAllElem c ENDIF * * Step 4 Process this elements attributes * Get pointer to a NamedNodeMap C EVAL Nodemapptr@ = QxmlDOM_Node_getAttributes C (nodlstptr@) c IF Nodemapptr@ = *NULL c ELSE * If phone node, get attribute to check match in MAPADDRESS table c IF element = 'Phone' c EVAL Nodeptr@ = QxmlDOM_NamedNodeMap_item C (Nodemapptr@:0) c EVAL Domstrptr@ = QxmlDOM_Node_getNodeValue C (Nodeptr@) * Set phonetype to work or home C EVAL phonetype = %str( C QxmlDomString_transcode(Domstrptr@)) C CALLP QxmlDomString_delete(Domstrptr@) C CALLP QxmlDOM_Node_delete(nodeptr@) c ENDIF c EVAL numAttr = QxmlDOM_NamedNodeMap_getLength c (Nodemapptr@) c EVAL k=0 c DOW k < numAttr * Loop through the attributes if any c EVAL Nodeptr@ = QxmlDOM_NamedNodeMap_item C (Nodemapptr@:k) c EVAL Domstrptr@ = QxmlDOM_Node_getNodeName c (Nodeptr@) C EVAL attrElem= %str( C QxmlDomString_transcode(Domstrptr@)) C CALLP QxmlDOMString_delete(Domstrptr@) c EVAL hxmlpath = %trimr(bigLongStr) + attrElem * Check if match in MAPADDRESS file c EXSR getDBValue c IF hvalue = -1 c ELSE * Determine which host variable value needs to be set c EVAL Domstrptr@ = QxmlDOM_Node_getNodeValue C (Nodeptr@) C EVAL attrVal= %str( C QxmlDOMString_transcode(Domstrptr@)) C CALLP QxmlDOMString_delete(Domstrptr@) c EVAL hostVal = attrVal c EXSR setString c ENDIF C CALLP QxmlDOM_Node_delete(Nodeptr@) c EVAL k = k + 1 c ENDDO C CALLP QxmlDOM_NamedNodeMap_delete(Nodemapptr@) c ENDIF * * Step 5 Process the current elements text content * Loop through child nodes if any C EVAL child = QxmlDOM_Node_hasChildNodes C (NodLstPtr@) c IF child = Qxml_HASCHILD * Get the pointer to list of child dom_nodes C* EVAL ChlNodLst@ = C* QxmlDOM_Node_getChildNodes(NodLstPtr@) c EVAL Nodeptr@ = QxmlDOM_Node_getFirstChild C (NodLstPtr@) * If text node, get the value if there is one C IF QxmlDOM_Node_getNodeType(Nodeptr@) = C Qxml_TEXT_NOD C EVAL Domstrptr@ = QxmlDOM_Node_getNodeValue C (Nodeptr@) C EVAL childVal = %str( C QxmlDOMString_transcode(Domstrptr@)) C CALLP QxmlDOMString_delete(Domstrptr@) c EVAL valueLen = %len(%trimr(childVal)) * Check against 1 since %len gives back 1 even when it seems blank * stopgap measure, If you check childVal for *blanks it doesn't * think it is blank. c IF valueLen > 1 C EVAL Domstrptr@ = QxmlDOM_Node_getNodeName C (Nodeptr@) C EVAL childElem = %str( C QxmlDOMString_transcode(Domstrptr@)) C CALLP QxmlDOMString_delete(Domstrptr@) c c IF element = 'Phone' C EVAL hxmlpath = %trimr(bigLongStr) + phonetype c EXSR getDBValue c ELSE c EVAL hxmlpath = bigLongStr c EXSR getDBValue c ENDIF * Set the Host value for the SQL statement c IF hvalue = -1 c ELSE c EVAL hostVal = childVal c EXSR setString c ENDIF c ENDIF c ENDIF C CALLP QxmlDOM_Node_delete(Nodeptr@) c ENDIF * End big loop c EVAL i = i + 1 C CALLP QxmlDOM_NodeList_delete(NodLstPtr@) c ENDDO * Update for last address c EXSR Insert C ELSE * Print error if no elements in document c EXCEPT ErrNoElem C ENDIF * You're done. Do the cleanup and exit C EXSR Cleanup C RETURN * C Cleanup BEGSR * Cleanup the objects created by the C++ parser C CALLP QxmlDOM_Document_delete(DomDoc@) C CALLP QxmlDOM_NodeList_delete(DomNodeList@) C CALLP QxmlDOMParser_delete(DomParse@) C DEALLOC XmlFile@ C DEALLOC GetTagOpt@ C CALLP QxmlTerm * Cleanup the memory created by the vector code c callp FreeElem * Print out a detail line C EXCEPT DETAIL C ENDSR C* C getDBValue BEGSR C* c* Access MAPADDRESS table, INPUT is the parentage for the c* current element. If a match is found in the MAPADDRESS file, c* the HVALUE field is RETURNED. c* c EVAL hvalue = -1 C/EXEC SQL Declare C1 Cursor For C+ SELECT VALUE FROM XML4PR310/MAPADDRESS C+ WHERE XMLPATH = :HXMLPATH c+ For Fetch Only C/END-EXEC C* Open the cursor C/EXEC SQL C+ Open C1 C/END-Exec C* Retrieve the value C/EXEC SQL C+ fetch C1 into :hvalue C/end-exec C* If record not found c IF SqlStt = '02000' c EVAL hvalue = -1 c ENDIF C* Close the cursor C/Exec SQL C+ close C1 C/END-Exec C ENDSR C* C setString BEGSR c SELECT c WHEN hvalue = 1 c EVAL HFNAME = hostVal c WHEN hvalue = 2 c EVAL HMNAME = hostVal c WHEN hvalue = 3 c EVAL HLNAME = hostVal c WHEN hvalue = 4 c EVAL HTITLE = hostVal c WHEN hvalue = 5 c EVAL HADDTYPE = hostVal c WHEN hvalue = 6 c EVAL HSTREET = hostVal c WHEN hvalue = 7 c EVAL HCITY = hostVal c WHEN hvalue = 8 c EVAL HSTATE = hostVal c WHEN hvalue = 9 c EVAL HPOSTALC = hostVal c WHEN hvalue = 10 c EVAL HCOUNTRY = hostVal c WHEN hvalue = 11 c EVAL HEMAIL = hostVal c WHEN hvalue = 12 c EVAL HHPHONE = hostVal c WHEN hvalue = 13 c EVAL HWPHONE = hostVal c END C ENDSR C* C Insert BEGSR C/Exec SQL INSERT C+ INTO XML4PR310/ADRESSBK C+ (FIRSTNAME, MIDDLENAME, LASTNAME, TITLE, ADDRESS, STREET, C+ CITY, STATE, POSTALCODE, COUNTRY, EMAIL, HOMEPHONE, C+ WORKPHONE) C+ VALUES(:HFNAME, C+ :HMNAME, C+ :HLNAME, C+ :HTITLE, C+ :HADDTYPE, C+ :HSTREET, C+ :HCITY, C+ :HSTATE, C+ :HPOSTALC, C+ :HCOUNTRY, C+ :HEMAIL, C+ :HHPHONE, C+ :HWPHONE) C+ C/End-Exec C/Exec SQL C+ commit C/end-exec C ENDSR c* c* Insert * into insert statement as filler in case document C* doesn't contain information for that field. c* C InsertStar BEGSR C EVAL HFNAME = '*' C EVAL HMNAME = '*' C EVAL HLNAME = '*' C EVAL HTITLE = '*' C EVAL HADDTYPE = '*' C EVAL HSTREET = '*' C EVAL HCITY = '*' C EVAL HSTATE = '*' C EVAL HPOSTALC = '*' C EVAL HCOUNTRY = '*' C EVAL HEMAIL = '*' C EVAL HHPHONE = '*' C EVAL HWPHONE = '*' C ENDSR OQPRINT E DETAIL 1 O +0 'Element count is' O elemCount Z +1 O +1 'for file' O XmlFile +1 OQPRINT E ErrNoElem 1 O +0 'No elements in file' O XmlFile +1