Interrogate XML Content Containing Namespaces

   Exchange Pre-configured Maestro services.  |   Platform Developer |  All versions   This feature is related to v5.1 and higher.

So you've written a Groovy service that calls a web service and gets a response back that looks something like this:

<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">
    <env:Header>
    </env:Header>
    <env:Body>
        <env:Fault xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">
            <faultcode>env:Server</faultcode>
            <faultstring>Errors with input data</faultstring>
            <detail>
                <ns2:faultDetails xmlns:ns2="http://schemas.myorg.com/idv/">
                    <code>FieldValidationFault</code>
                    <details>Invalid Medicare number</details>
                </ns2:faultDetails>
                <ns2:faultDetails xmlns:ns2="http://schemas.myorg.com/idv/">
                    <code>FieldValidationFault</code>
                    <details>Invalid Passport number</details>
                </ns2:faultDetails>
            </detail>
        </env:Fault>
    </env:Body>
</env:Envelope>

 

You can interrogate this XML structure using the Path utility class with one of the following approaches:

Namespace notation XPath

The Path class will resolve namespaces automatically for you so you can perform XPath queries using namespace notation:

Path xmlPath = new Path(xmlData)
List<Path> subPaths = xmlPath.paths('//ns2:faultDetails')

The XPath name() or local-name() approach

If you're an XPath guru, you will already know that you can structure an XPath query to skirt around the namespace resolution issue using the local-name directive. The following code works against the XML above to retrieve the two sub paths:

<Path> subPaths = xmlPath.paths('//*[local-name()="faultDetails"]')

Alternatively you could use the name directive with the namespace included as follows:

List<Path> subPaths = xmlPath.paths('//*[name()="ns2:faultDetails"]')

This type of query requires a deeper knowledge of the XPath syntax for this more advanced type of query and is a lot less readable than simple queries, but does offer a simple way to achieve the desired result.