首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Groovy MarkupBuilder名称冲突

Groovy MarkupBuilder名称冲突
EN

Stack Overflow用户
提问于 2012-07-09 11:40:54
回答 1查看 1.5K关注 0票数 5

我有这样的代码:

代码语言:javascript
复制
String buildCatalog(Catalog catalog) {
    def writer = new StringWriter()
    def xml = new MarkupBuilder(writer)
    xml.catalog(xmlns:'http://www.sybrium.com/XMLSchema/NodeCatalog') {
        'identity'() {
            groupId(catalog.groupId)
            artifactId(catalog.artifactId)
            version(catalog.version)
        }
    }

    return writer.toString();
}

它生成以下xml:

代码语言:javascript
复制
<catalog xmlns='http://www.sybrium.com/XMLSchema/NodeCatalog'>
  <groupId>sample.group</groupId>
  <artifactId>sample-artifact</artifactId>
  <version>1.0.0</version>
</catalog>

请注意,"identity“标签丢失了...为了让那个节点出现,我尝试了世界上所有的方法。我要把头发拔出来了!

提前谢谢。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-07-09 12:20:14

也许有一种更好的方法,但是有一个技巧是直接调用invokeMethod

代码语言:javascript
复制
String buildCatalog(Catalog catalog) {
    def writer = new StringWriter()
    def xml = new MarkupBuilder(writer)
    xml.catalog(xmlns:'http://www.sybrium.com/XMLSchema/NodeCatalog') {
        delegate.invokeMethod('identity', [{
            groupId(catalog.groupId)
            artifactId(catalog.artifactId)
            version(catalog.version)
        }])
    }

    return writer.toString();
}

这实际上就是Groovy在幕后做的事情。我无法让delegate.identityowner.identity工作,这是常见的技巧。

编辑:我知道是怎么回事了。

对每个对象使用identity(Closure c)签名的Groovy adds a method

这意味着,当您试图在传递单个闭包参数的同时动态调用XML构建器上的identity元素时,它调用的是identity()方法,这类似于在外部闭包上调用delegate({...})

使用invokeMethod技巧会迫使Groovy绕过元对象协议,并将该方法视为动态方法,即使MetaObject上已经存在identity方法。

了解了这一点,我们就可以提出一个更好、更清晰的解决方案。我们所要做的就是更改方法的签名,如下所示:

代码语言:javascript
复制
String buildCatalog(Catalog catalog) {
    def writer = new StringWriter()
    def xml = new MarkupBuilder(writer)
    xml.catalog(xmlns:'http://www.sybrium.com/XMLSchema/NodeCatalog') {
        // NOTE: LEAVE the empty map here to prevent calling the identity method!
        identity([:]) {
            groupId(catalog.groupId)
            artifactId(catalog.artifactId)
            version(catalog.version)
        }
    }

    return writer.toString();
}

这样做的可读性更好,意图更清晰,注释应该(希望)防止任何人删除“不必要的”空map。

票数 12
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11388838

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档