在Groovy Markup Builder中使用外部字符串变量

时间:2014-03-19 12:48:19

标签: groovy markupbuilder

我使用groovy中的一些逻辑创建了一个字符串变量,它反映了标记构建器中的braket语法,但问题是显然不允许在标记构建器中使用此字符串。我的代码的性质使它成为必要。我想知道是否有办法做类似下面的事情

def param = "node1{ node2{ node3() } }"
def sw = new StringWriter()
def xml = new groovy.xml.MarkupBuilder(sw)

XML = xml.param

我知道上面的代码不正确但是有没有办法做我正在开车的东西?要清楚param是一个字符串,它是另一段代码的产物。我希望得到一个像以下一样的XML:

<node1><node2><node3/></node2><node1>

由于

1 个答案:

答案 0 :(得分:2)

如果你将你的闭包string更改为(我称之为builder,因为我并不热衷于将较低级别的类名作为属性名称)

def builder = { ->
    node1 {
        node2{
            node3()
        }
    }
}

然后,您可以使用StreamingMarkupBuilder执行此操作:

String output = new groovy.xml.StreamingMarkupBuilder().bind { 
    builder.delegate = delegate
    builder()
}.toString()

output将包含字符串:

<node1><node2><node3/></node2></node1>

编辑:

看起来我误解了,param变量是一个字符串。在这种情况下,您可以这样做来评估String(包装在一个闭包中),并执行与上面相同的操作:

def param = "node1 { node2 { node3() } }"

String output = new groovy.xml.StreamingMarkupBuilder().bind { smb ->
    Eval.me( "{ -> $param }" ).with { c ->
        c.delegate = smb
        c()
    }
}.toString()

但是应该注意,在使用Eval做任何事情时都必须小心。它不会关心代码是恶意的还是良性的,它只是运行它,可能会崩溃您的应用程序或删除代码或更糟。

也许不是建立一个String,你可以建立一个地图或什么?然后你可以做这样的事情:

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 ) }
    }
}