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>