I'm iterating through the child elements of a flattish XML, and adding a certain attribute for elements that are empty.
import groovy.xml.XmlUtil
import groovy.xml.MarkupBuilder
import groovy.xml.XmlSlurper
def xmlTxt = '''<root>
<node>
<element/>
<element/>
</node>
</root>'''
def xml = new XmlSlurper().parseText(xmlTxt)
xml.node.'*'.each {
if ( it == "") {
it.'@foo' = "bar"
}
}
return XmlUtil.serialize(xml)
The result for this is
<?xml version="1.0" encoding="UTF-8"?><root>
<node>
<element foo="bar"/>
<element foo="bar"/>
</node>
</root>
Now, my real requirement is to change the element so that <element xsi:nil="true"/>, where xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
I've tried using .declareNamespace(xsi:'http://www.w3.org/2001/XMLSchema-instance') when creating the XmlSlurper instance, and then it.'@xsi:nil' = 'true' when adding the attribute, but this results in an error. Is there a quick way to accomplish this with the syntax I'm using?
Here is the best I could come up with:
The issue you were having was that it didn't know about the
xsinamespace because it wasn't in your root node definition. Using thedeclareNamespacewasn't working either since it didn't see that definition. I suspect it was added after the parsing so it couldn't see it. There are some mentions of this in the docs.I tried putting the namespace definition directly in the XML:
...but it still didn't seem to see it when I added the
@xsi:nilattribute to the element.The only thing that worked was replacing the node with a newly defined node that included the
xmlns:xsidefinition. Otherwise it was "unbounded" and an error was thrown.I also checked
XmlParserin case it handled namespaces differently, but it was pretty much the same result asXmlSlurper. I included the code should you want to experiment with it too.That's about as close as I could get it.