Typical use of the builder starts with:
import groovy.xml.MarkupBuilder def writer = new StringWriter() def xml = new MarkupBuilder(writer) ... String generatedXml = writer.toString()
Then the “building” part is what’s not documented all that well.
Fundamentals
To get element and value:
xml.Outer("hello")
Output:
<Outer>hello</Outer>
To add attributes, pass them as a map to the function:
xml.Outer(xmlns:'http://www.abc.com/blahblahblah')
Output:
<Outer xmlns:"http://www.abc.com/blahblahblah" />
To add children, add a closure in which to add more tags:
xml.Outer(xmlns:'http://www.abc.com/blahblahblah') { Inner("inner val") }
Output:
<Outer xmlns:"http://www.abc.com/blahblahblah"> <Inner>inner val</Inner> </Outer>
Adding some attributes AND value to Inner:
xml.Outer(xmlns:'http://www.abc.com/blahblahblah') { Inner(id:"myId", "inner val") }
Output:
<Outer xmlns:"http://www.abc.com/blahblahblah"> <Inner id="myId">inner val</Inner> </Outer>
NOTE how the Inner() call: it’s a Map followed by a String.
Loops
Turns out we can add code (such as loops) inside the closure:
xml.Outer(xmlns:'http://www.abc.com/blahblahblah') { Inner(id:"myId", "inner val") (1..5).each {i -> MoreInner("innerChild ${i}") } }
Output:
<Outer xmlns='http://www.abc.com/blahblahblah'> <Inner id='myId'>inner val</Inner> <MoreInner>innerChild 1</MoreInner> <MoreInner>innerChild 2</MoreInner> <MoreInner>innerChild 3</MoreInner> <MoreInner>innerChild 4</MoreInner> <MoreInner>innerChild 5</MoreInner> </Outer>
Other than loops, more sophisticated code can be used. But that will complicate the code. Which brings us to functions.
Function calls
def addInnerChildren(builder) { builder.Inner(id:"myId", "inner val") { (1..5).each {i -> MoreInner("innerChild ${i}") } } } xml.Outer(xmlns:'http://www.abc.com/blahblahblah') { addInnerChildren(xml) }
Output:
<Outer xmlns='http://www.abc.com/blahblahblah'> <Inner id='myId'>inner val</Inner> <MoreInner>innerChild 1</MoreInner> <MoreInner>innerChild 2</MoreInner> <MoreInner>innerChild 3</MoreInner> <MoreInner>innerChild 4</MoreInner> <MoreInner>innerChild 5</MoreInner> </Outer>
Prefix for namespace
It’s a bit cumbersome; we have to quote the “tag”:
xml.'hahaha:Outer'('xmlns:hahaha': 'http://www.abc.com/blahblahblah') { whatever('floats') 'hahaha:your'('boat') }
Output:
<hahaha:Outer xmlns:hahaha='http://www.abc.com/blahblahblah'> <whatever>floats</whatever> <hahaha:your>boat</hahaha:your> </hahaha:Outer>
Dynamic tags
Finally, if we do not know the exact tag yet:
String tag = "hahaha" ... xml."${tag}"(xmlns: 'http://www.abc.com/blahblahblah') { whatever('floats your boat') }
Output:
<hahaha xmlns='http://www.abc.com/blahblahblah'> <whatever>floats your boat</whatever> </hahaha>