One way to get a list of usable namespaces is to visit each element and get a URI namespace:
def s = """ <?xml version="1.0" encoding="utf-8"?> <b:root xmlns:a="http://a.example.com" xmlns:b="http://b.example.com" xmlns:c="http://c.example.com" xmlns:d="http://d.example.com"> <a:name>Test A</a:name> <b:name>Test B</b:name> <b:stuff> <c:foo>bar</c:foo> <c:baz> <d:foo2/> </c:baz> </b:stuff> <nons>test</nons> <c:test/> </b:root> """.trim() def xml = new XmlSlurper().parseText(s) def namespaceList = xml.'**'.collect { it.namespaceURI() }.unique() assert ['http://b.example.com', 'http://a.example.com', 'http://c.example.com', 'http://d.example.com', ""] == namespaceList
Another way is to use reflection to access the protected property namespaceTagHints of the GPathResult class, which is a superclass of groovy.util.slurpersupport.NodeChild.
def xml = new XmlSlurper().parseText("<...>") def xmlClass = xml.getClass() def gpathClass = xmlClass.getSuperclass() def namespaceTagHints = gpathClass.getDeclaredField("namespaceTagHints") namespaceTagHints.setAccessible(true) println namespaceTagHints.get(xml) // returns ==> [b:http://b.example.com, a:http://a.example.com, d:http://d.example.com, c:http://c.example.com]
Just a note. By default, XmlSlurper does not require a namespace declaration to move around the document, so as long as the names of the elements / attributes are unique, you usually don't need to worry about namespaces.
source share