TL;DR: When in the start subprocedure specified in the call to http_parse_xml_stmf, the attributes pointer seems to be null and I can't retrieve attributes until the end subprocedure runs.
Background: I am using version 1.39 of Scott Klements HTTP_API open source project to parse an XML document. The XML document is downloaded via a third party product and not via HTTP_API. The vendor is working on adding support for the contents of this particular XML document but it won't be ready in time for a quickly approaching deadline. Additionally, the vendor does all the heavy lifting regarding authentication and writing to the IFS during the download request. In the meantime, I am using http_parse_xml_stmf to parse the XML document. The only thing I modified regarding the attached XML document is I made it much smaller and changed the contents since it did contain sensitive information. Other than that, it is a straight download from the IBM i using the IBM i Navigator and then a save using Notepad++.
Explanation and Issue: I need to get the attributes from the Request element in the attached XML document but it appears as though the attributes pointer is null when the StartOfElement subprocedure runs. However, when the EndOfElement subprocedure runs, I can retrieve the attributes. Scott's Example11 also shows retrieving attributes in the end subprocedure. However, on PDF page 15 of the handout for a retired presentation of Scott's titled XML From RPG Using Free Tools it says in part: "Usually, the Start Element Handler has two important goals: • To keep track of the position in the document (create an Xpath) • To parse the attributes". I realize this is a retired presentation but I am making an assumption that what was said still holds true because the presentation talks about Expat which is still used in HTTP_API from what I understand. Perhaps that is a false assumption and my understanding of HTTP_API is incorrect.
My Procedure Interface for StartOfElement looks like this and was modeled after a combination of his Example10 and Example14:
Code:
D StartOfElement PI D xmlDataIn likeds(xmlData) D depth 10I 0 value D name 1024A varying const D path 24576A varying const D value 65535A varying const D attrs * dim(32767) D const options(*varsize)
Code:
D EndOfElement PI D xmlDataIn likeds(xmlData) D depth 10I 0 value D name 1024A varying const D path 24576A varying const D value 65535A varying const D attrs * dim(32767) D const options(*varsize)
Code:
EVAL attrs ATTRS(1) = SPP:*NULL ATTRS(2) = SPP:*NULL ATTRS(3) = SPP:*NULL ATTRS(4) = SPP:*NULL ATTRS(5) = SPP:*NULL ATTRS(6) = SPP:*NULL ATTRS(7) = SPP:*NULL ATTRS(8) = SPP:*NULL ATTRS(9) = SPP:*NULL ATTRS(10) = SPP:*NULL ATTRS(11) = SPP:*NULL ATTRS(12) = SPP:*NULL ATTRS(13) = SPP:*NULL
Code:
EVAL attrs ATTRS(1) = SPP:E7EB0DEE7B03FA60 ATTRS(2) = SPP:E7EB0DEE7B03FA90 ATTRS(3) = SPP:E7EB0DEE7B03FAD0 ATTRS(4) = SPP:E7EB0DEE7B03FB00 ATTRS(5) = SPP:E7EB0DEE7B03FB40 ATTRS(6) = SPP:E7EB0DEE7B03FB70 ATTRS(7) = SPP:E7EB0DEE7B03FBA0 ATTRS(8) = SPP:E7EB0DEE7B03FBE0 ATTRS(9) = SPP:E7EB0DEE7B03FC30 ATTRS(10) = SPP:E7EB0DEE7B03FC60 ATTRS(11) = SPP:E7EB0DEE7B03FC80 ATTRS(12) = SPP:E7EB0DEE7B03FCC0 ATTRS(13) = SPP:E7EB0DEE7B03FD10
StartOfElement
Code:
if path = '/Report/Requests/Request'; count = 1; dow http_nextXmlAttr(attrs: count: attrName: attrVal); select; when attrName = 'RequestID'; attribute = attrVal; xmlRequestID = attrVal; xmlDataIn.requestID = attrVal; when attrName = 'MerchantID'; attribute = attrVal; xmlMerchantId = attrVal; xmlDataIn.merchantId = attrVal; when attrName = 'MerchantReferenceNumber'; attribute = attrVal; xmlMerchRefCode = attrVal; xmlDataIn.merchRefCode = attrVal; endsl; enddo; endif;
Code:
if path = '/Report/Requests/Request'; count = 1; dow http_nextXmlAttr(attrs: count: attrName: attrVal); select; when attrName = 'RequestID'; attribute = attrVal; xmlRequestID = attrVal; xmlDataIn.requestID = attrVal; when attrName = 'MerchantID'; attribute = attrVal; xmlMerchantId = attrVal; xmlDataIn.merchantId = attrVal; when attrName = 'MerchantReferenceNumber'; attribute = attrVal; xmlMerchRefCode = attrVal; xmlDataIn.merchRefCode = attrVal; endsl; enddo; endif;
When invoking the subprocedure, http_parse_xml_stmf, this is my code:
Code:
if (http_parse_xml_stmf( %trim(FilepathSv) : HTTP_XML_CALC : %paddr(StartOfElement) : %paddr(EndOfElement) : %addr(xmlData)) < 0 ); errorMessage = http_error(); return; endif;
Comment