Change XML Tag Name

I want to convert an XML document that I parsed using XmlSlurper . The names (identical) of the XML tags must be replaced with the id attribute value; all other attributes must be removed. Starting from this code:

 def xml = """<tag id="root"> | <tag id="foo" other="blah" more="meh"> | <tag id="bar" other="huh"/> | </tag> |</tag>""".stripMargin() def root = new XmlSlurper().parseText(xml) // Some magic here. println groovy.xml.XmlUtil.serialize(root) 

I want to get the following:

 <root> <foo> <bar/> </foo> </root> 

(I am writing test statements in XML and I want to simplify the structure for them.) I read the XML Update using XmlSlurper and, but did not find a path with replaceNode() or replaceBody() to exchange the node, while retaining its children.

+6
source share
1 answer

Adding "magic" to the code in the question gives:

 def xml = """<tag id="root"> | <tag id="foo" other="blah" more="meh"> | <tag id="bar" other="huh"/> | </tag> |</tag>""".stripMargin() def root = new XmlSlurper().parseText(xml) root.breadthFirst().each { n -> n.replaceNode { "${ n.@id }"( n.children() ) } } println groovy.xml.XmlUtil.serialize(root) 

What prints:

 <?xml version="1.0" encoding="UTF-8"?><root> <foo> <bar/> </foo> </root> 

HOWEVER, this will result in the loss of any content in the nodes. To maintain content, we probably need to use recursion and XmlParser to create a new document from an existing one ... I will have a thought

More general solution

I think this is more general:

 import groovy.xml.* def xml = """<tag id="root"> | <tag id="foo" other="blah" more="meh"> | <tag id="bar" other="huh"> | something | </tag> | <tag id="bar" other="huh"> | something else | </tag> | <noid>woo</noid> | </tag> |</tag>""".stripMargin() def root = new XmlParser().parseText( xml ) def munge( builder, node ) { if( node instanceof Node && node.children() ) { builder."${ node.@id ?: node.name()}" { node.children().each { munge( builder, it ) } } } else { if( node instanceof Node ) { "${ node.@id ?: node.name()}"() } else { builder.mkp.yield node } } } def w = new StringWriter() def builder = new MarkupBuilder( w ) munge( builder, root ) println XmlUtil.serialize( w.toString() ) 

And prints:

 <?xml version="1.0" encoding="UTF-8"?><root> <foo> <bar>something</bar> <bar>something else</bar> <noid>woo</noid> </foo> </root> 

Now goes through nodes without attributes (or empty) id

+5
source

All Articles