Namespace handling in Groovys XmlSlurper

codeporn picture codeporn · Dec 29, 2011 · Viewed 12.4k times · Source

The situation:

def str = """
  <foo xmlns:weird="http://localhost/">
    <bar>sudo </bar>
    <weird:bar>make me a sandwich!</weird:bar>
  </foo>
"""
def xml = new XmlSlurper().parseText(str)
println xml.bar

The output of this snippet is

# sudo make me a sandwich!

It seems like the parser merges the contents of <bar> and <weird:bar>.

Is this behavior desired and if yes, how can I avoid this and select only <bar> or <weird:bar>?

Answer

Kai Sternad picture Kai Sternad · Dec 29, 2011

By default XMLSlurper is not namespace aware. This can be turned on by declaring namespaces with the declareNamespace Method.

def str = """ 
<foo xmlns:weird="http://localhost/">
  <bar>sudo </bar>
  <weird:bar>make me a sandwich!</weird:bar>
</foo>
""" 
def xml = new XmlSlurper().parseText(str).declareNamespace('weird':'http://localhost/')
println xml.bar // without namespace awareness, will print "sudo make me a sandwich!"
println xml.':bar' // will only print "sudo"
println xml.'weird:bar' // will only print "make me a sandwich!"

The output is:

sudo make me a sandwich!
sudo
make me a sandwich!

The first println will still not be namespace aware. The second println will only print the tag without namespace. If you qualify element with the prefix shown in the third println you only get the namespaced tag.