If you change your closure string
to be (I've called it builder
as I'm not keen on lower-cased class names as property names)
def builder = { ->
node1 {
node2{
node3()
}
}
}
You can then do this with StreamingMarkupBuilder
:
String output = new groovy.xml.StreamingMarkupBuilder().bind {
builder.delegate = delegate
builder()
}.toString()
And output
will contain the String:
<node1><node2><node3/></node2></node1>
Edit:
Looks like I misunderstood and the param
variable is a String. In that case, you can do this to evaluate the String (wrapped in a closure) and do much the same as above:
def param = "node1 { node2 { node3() } }"
String output = new groovy.xml.StreamingMarkupBuilder().bind { smb ->
Eval.me( "{ -> $param }" ).with { c ->
c.delegate = smb
c()
}
}.toString()
It should be noted however, that care must be taken when doing anything with Eval. It won't care if the code is malicious, or benign, it will just run it, possibly crashing your app or deleting code or worse.
Maybe instead of building a String, you could build a map or something? Then you could do something like this:
def param = [ node1:[ node2:[ node3:'' ] ] ]
String output = new groovy.xml.StreamingMarkupBuilder().bind {
param.each { k, v ->
"$k" { v instanceof Map ? v.each( owner ) : mkp.yield( v ) }
}
}