0

When I create XMLSlurper without validation and namespace awareness:

new XmlSlurper(false, false)

I subsequently cannot find any nodes with node.depthFirst().findAll().

The following code illustrates my issue:

def xml = '''<?xml version="1.0" encoding="UTF-8"?>
<cus:Customizations xmlns:cus="http://www.bea.com/wli/config/customizations" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xt="http://www.bea.com/wli/config/xmltypes">
    <cus:customization xsi:type="cus:EnvValueActionsCustomizationType">
        <cus:description/>
        <cus:actions>
            <xt:replace>
                <xt:envValueType>Service URI</xt:envValueType>
                <xt:location>0</xt:location>
                <xt:value xsi:type="xs:string" xmlns:xs="http://www.w3.org/2001/XMLSchema">http://myUrl.com</xt:value>
            </xt:replace>
        </cus:actions>
    </cus:customization>
</cus:Customizations>'''

/* The following code finds no nodes. */
def envelope1 = new XmlSlurper(false, false).parseText(xml)
def replaces1 = envelope1.depthFirst().findAll { node ->
    (node.name() == "replace")
}
assert replaces1.size() == 0

/* The following code finds one node (works as I expect). */
def envelope2 = new XmlSlurper().parseText(xml)
def replaces2 = envelope2.depthFirst().findAll { node ->
    (node.name() == "replace")
}
assert replaces2.size() == 1

Is it a known bug or am I missing something?

KarelHusa
  • 1,995
  • 18
  • 26
  • 1
    If you are asking the parser not to provide support for XML namespace, shouldn't the logic inside findAll be `(node.name() == "xt:replace")`, which is, specifying the node name as it is. – dmahapatro Feb 02 '17 at 14:04
  • Yes, when I look for "xt:replace" the node is found. I had a different understanding what "namespaceAware" means. I assumed it means ignoring the namespaces. As far as I know the element name cannot contain colon as colon is reserved for namespace assignment. But here the "xt:" prefix is treated as part of the name. XmlSlurper behavior seems to me confusing. Also when a namespace prefix changes, which is common, the program stops working. – KarelHusa Feb 02 '17 at 14:36
  • 1
    So why not use `def envelope1 = new XmlSlurper(false, true).parseText(xml)`, so the validation is turned off, but it is namespace aware... – tim_yates Feb 02 '17 at 15:03
  • Thank you @dmahapatro, it works as you suggested. – KarelHusa Feb 02 '17 at 16:55

1 Answers1

0

When XmlSlurper's property namespaceAware is set to false, we need to treat the namespace prefix as a part of the element name, i.e. when we look for an element:

(node.name() == "xt:replace")

This behavior of XmlSlurper does not seem correct to me, but it's the way it works. Double colon (:) cannot be part of the XML element name and is reserved for namespace usage. My conclusion is that I am going to use namespaceAware set to true in the future.

Thanks @dhamapatro for your help.

KarelHusa
  • 1,995
  • 18
  • 26