Jam*_*ins 5 groovy markupbuilder
我有这个代码:
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();
}
Run Code Online (Sandbox Code Playgroud)
它产生这个xml:
<catalog xmlns='http://www.sybrium.com/XMLSchema/NodeCatalog'>
<groupId>sample.group</groupId>
<artifactId>sample-artifact</artifactId>
<version>1.0.0</version>
</catalog>
Run Code Online (Sandbox Code Playgroud)
请注意,"身份"标签丢失了...我已经尝试了世界上的所有内容来显示该节点.我正在撕开我的头发!
提前致谢.
Ove*_*ous 11
可能有更好的方法,但一个技巧是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();
}
Run Code Online (Sandbox Code Playgroud)
这实际上是Groovy在幕后所做的事情.我无法上班delegate.identity或owner.identity下班,这是常用的伎俩.
编辑:我弄清楚发生了什么.
Groovy 为每个对象添加了一个签名的方法identity(Closure c).
这意味着当您尝试动态调用identityXML构建器上的元素时,在传入单个闭包参数时,它正在调用identity()方法,这就像调用delegate({...})外部闭包一样.
使用该invokeMethod技巧迫使Groovy绕过元对象协议并将该方法视为动态方法,即使该identity方法已存在于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();
}
Run Code Online (Sandbox Code Playgroud)
这更具可读性,意图更清晰,评论应该(希望)阻止任何人删除"不必要的"空地图.
| 归档时间: |
|
| 查看次数: |
1314 次 |
| 最近记录: |