Skip to content

Updating Namespaced Attributes With Groovy’s XmlSlurper

A recent question on the Groovy mailing list asked

I need to update the “xlink:title” attribute in:

<gmi:instrument xlink:title=”$INSTRUMENT”/>

Here’s what I came up with:

import groovy.xml.*

def xmlSource = '''
<bob:root xmlns:bob="stuff"
  xmlns:gmi="http://www.isotc211.org/2005/gmi"
  xmlns:xlink="http://www.w3.org/1999/xlink">
  <gmi:instrument xlink:title="$INSTRUMENT"/>
</bob:root>
'''

def bobRoot = new XmlSlurper(false,true).
                parseText(xmlSource).
                declareNamespace(bob: 'stuff',
                                 ns2: 'http://www.example.org/NS2',
                                 gmi: "http://www.isotc211.org/2005/gmi")

def instrument = bobRoot.'gmi:instrument'

// NB: does NOT work: instrument[0].attributes().remove('xlink:title')
// NB: works, but YUK: instrument[0].attributes().remove('{http://www.w3.org/1999/xlink}title')

// NB: leads to duplicate attribute: instrument.'@xlink:title' = 'XXX'
instrument.'@{http://www.w3.org/1999/xlink}title' = 'XXX'

println new StreamingMarkupBuilder().bind {
  mkp.yield instrument
}.toString()

'OK'

The key here is finding out that you need to use the full namespaced name, not the shorter name.

IMHO, this is a bug and I have created GROOVY-6356 using this code.

I’m also wondering why I needed to use ‘instrument[0]‘ to get at the attributes.

All this is more obscure and convoluted than it probably needs to be so keep watching the Jira.

Tags: ,

C, Java Enterprise Edition, JEE, J2EE, JBoss, Application Server, Glassfish, JavaServer Pages, JSP, Tag Libraries, Servlets, Enterprise Java Beans, EJB, Java Messaging Service JMS, BEA Weblogic, JBoss, Application Servers, Spring Framework, Groovy, Grails, Griffon, GPars, GAnt, Spock, Gradle, Seam, Open Source, Service Oriented Architectures, SOA, Java 2 Standard Edition, J2SE, Eclipse, Intellij, Oracle Service Bus, OSB