繁体   English   中英

如何使用Groovy的MarkupBuilder呈现List

[英]How to render a List with Groovy's MarkupBuilder

我正在使用Groovy MarkupBuilder将Map转换为XML。 此地图可以包含简单的键/值对,其他地图或地图列表。 我正在从这里的代码中捎带。

import groovy.xml.MarkupBuilder

def map = [
    key1:'value1',
    key2:'value2',
    nestedMap : [
        key1:'bar1',
        key2:'bar2'
    ],
    select : [
        [option:'foo1'],
        [option:'foo2']
    ]
]

Closure renderMap( Map map ){
    return { 
        for ( entry in map ){
            switch( entry.value.getClass() ){
                case Map :
                    "${entry.key}" renderMap( entry.value )
                break
                case List:
                    entry.value.collect { listEntry ->
                        "${entry.key}" renderMap( listEntry )
                    }
                    break
                default :
                     "${entry.key}"( "${entry.value}" )
                break
            }
        }
    }
}

StringWriter writer = new StringWriter()
new MarkupBuilder(writer).root renderMap(map)

println writer.toString()

这部分我关注打印出来:

  <select>
    <option>foo1</option>
  </select>
  <select>
    <option>foo2</option>
  </select>

但是,我想知道是否有办法让select封装两个选项,如下所示:

<select>
    <option>foo1</option>
     <option>foo2</option>
  </select>

我试过玩钥匙放置,但无济于事。 我是不是错了,或者我不应该使用建设者?

我想这会做你想要的。 前两个重载采用映射或集合,并返回一个组合闭包,该闭包可以传递给封闭元素的构建器方法,以将地图或集合的内容添加到构建器。

第三个是回退,只返回其参数,以便将它们传递给构建器方法。 这会处理字符串,但如果需要,您也可以将其传递给它。 我替换了您提供的地图中的第二个option元素作为示例。

在Groovy 1.8中添加了ComposedClosure ,因此在早期版本中不起作用。

import groovy.xml.MarkupBuilder

Closure buildxml(final Map map)
{
    final compose = { f, tag, content -> f >> { "$tag"(buildxml(content)) } }
    return map.inject(Closure.IDENTITY, compose)
}

Closure buildxml(final Collection col)
{
    final compose = { f, content -> f >> buildxml(content) }
    return col.inject(Closure.IDENTITY, compose)
}

def buildxml(final content)
{
    return content
}

def map = [
    key1:'value1',
    key2:'value2',
    nestedMap : [
        key1:'bar1',
        key2:'bar2'
    ],
    select : [
        [option:'foo1'],
        { option('foo2') },
    ],
]

final writer  = new StringWriter()
final builder = new MarkupBuilder(writer)

builder.root buildxml(map)

assert writer as String == '''\
<root>
  <key1>value1</key1>
  <key2>value2</key2>
  <nestedMap>
    <key1>bar1</key1>
    <key2>bar2</key2>
  </nestedMap>
  <select>
    <option>foo1</option>
    <option>foo2</option>
  </select>
</root>'''.stripIndent()

case List:
    "${entry.key}" entry.value.collect {
        renderMap it
    }
    break

带你去哪儿? 虽然不是在电脑上检查atm,但感觉对吗?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM