Groovy MarkupBuilder名称冲突
发布时间:2020-12-14 16:36:22 所属栏目:大数据 来源:网络整理
导读:我有这个代码: 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) artifactI
我有这个代码:
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: <catalog xmlns='http://www.sybrium.com/XMLSchema/NodeCatalog'> <groupId>sample.group</groupId> <artifactId>sample-artifact</artifactId> <version>1.0.0</version> </catalog> 请注意,“身份”标签丢失了…我已经尝试了世界上的所有内容来显示该节点.我正在撕开我的头发! 提前致谢. 解决方法
可能有更好的方法,但一个技巧是直接调用invokeMethod:
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.identity或owner.identity工作,这是常用的技巧. 编辑:我弄清楚发生了什么. Groovy adds a method带有每个对象的标识(Closure c). 这意味着当您尝试动态调用XML构建器上的identity元素时,在传入单个闭包参数时,它调用了identity()方法,就像在外部闭包上调用delegate({…})一样. 使用invokeMethod技巧强制Groovy绕过元对象协议并将该方法视为动态方法,即使MetaObject上已存在标识方法. 了解这一点,我们可以将更好,更清晰的解决方案整合在一起.我们所要做的就是更改方法的签名,如下所示: 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(); } 这更具可读性,意图更清晰,评论应该(希望)阻止任何人删除“不必要的”空地图. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |