You can use XmlParser and not XmlSlurper and do this:
def xml = '''<LinearLayout | xmlns:android="http://schemas.android.com/apk/res/android" | xmlns:b="http://xyzcom"> | | <EditText | android:layout_width="fill_parent" | android:layout_height="wrap_content" | b:enabled="true" /> |</LinearLayout>'''.stripMargin() def root = new XmlParser().parseText( xml ) root.EditText*.attributes()*.each { k, v -> println "$k.localPart $k.prefix($k.namespaceURI) = $v" }
What prints
layout_width android(http://schemas.android.com/apk/res/android) = fill_parent layout_height android(http://schemas.android.com/apk/res/android) = wrap_content enabled b(http://xyzcom) = true
Edit
To use XmlSlurper, you first need to access the namespaceTagHints property from the root of the node using reflection:
def rootNode = new XmlSlurper().parseText(xml) def xmlClass = rootNode.getClass() def gpathClass = xmlClass.getSuperclass() def namespaceTagHintsField = gpathClass.getDeclaredField("namespaceTagHints") namespaceTagHintsField.setAccessible(true) def namespaceDeclarations = namespaceTagHintsField.get(rootNode)
namespaceTagHints is a GPathResult property that is a superclass of NodeChild .
You can then cross-reference this map to access the namespace prefix and print the same result as above:
rootNode.EditText.nodeIterator().each { groovy.util.slurpersupport.Node n -> n.@attributeNamespaces.each { name, ns -> def prefix = namespaceDeclarations.find {key, value -> value == ns}.key println "$name $prefix($ns) = ${n.attributes()"$name"}" } }
source share