Thursday, July 1, 2021

Parsing SOAP XML Data with Default Namespaces Using UniBasic Extensions XPath

 This is another technical tidbit about the U2 UniBasic Extensions.

Most of the examples I could find about U2 XPath did not include namespace processing.  In my real-world application (integrating tax caclulations with Vertex SOAP based services) handling namespacing correctly was necessary.

XDOMLocate allows you to pass in a namespace map and this works fine for explicit namespace prefixes. It is a different story when the XML uses a default namespace and there is no prefix in the xml.

There is a secret (unexpected) trick to convincing U2 XPath that nodes with no prefix should be considered to belong to the identified default namespace.

Add an explicit prefix to the namespace map and use it in your XDOMLocate statements. You can make one up, I used 'd':

     nsMAP = 'xmlns=':VertexNamespace:' '
 * XDOM does not handle default namespace as expected, so create a dummy d: prefix to use in XPATH     
     nsMAP := 'xmlns:d=':VertexNamespace:' '
     nsMAP := 'xmlns:S=http://schemas.xmlsoap.org/soap/envelope/ '
     nsMAP := 'xmlns:nsf=http://schemas.xmlsoap.org/soap/envelope/ '
     nsMAP := 'xmlns:ns=urn:vertexinc:oseries:exception:1:0 '
     nsMAP := 'xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance'

And then, when you are looking for defaulted nodes with no prefix, format the XPath expression with the 'd:' prefix:

 * Look for a VertexEnvelope, normal geodata returns will contain one, error packets won't
     node = ''           
     RESPONSE.DATA.PATH = "//d:VertexEnvelope"
     LocateStatus = XDOMLocate(domHandle, RESPONSE.DATA.PATH, nsMAP, node) 
     IF (LocateStatus = XML.SUCCESS) THEN  
 * Valid results returned from Vertex so return SOAP.MSG document and no ERR.MSG.
        DMY = XDOMClose(domHandle) 
        RETURN 
     END

Not intuitive, but it gets the job done.