如何使用Groovy的MarkupBuilder渲染列表 [英] How to render a List with Groovy's MarkupBuilder

查看:148
本文介绍了如何使用Groovy的MarkupBuilder渲染列表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am converting a Map to XML using the Groovy MarkupBuilder. This Map can contain simple key/value pairs, other Maps, or Lists of Maps. I am piggybacking from the code here.

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

这部分我关心打印输出:

This part I'm concerned about prints out:

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

但是,我想知道是否有一种方法可以让选择封装这两个选项,像这样:

However, I am wondering if there is a way to get the select to encapsulate both of the options, like so:

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

我已经尝试着玩钥匙的位置,但没有效果。我正在做这个事情都是错的,还是我不应该使用构建器?

I've tried playing around with the placement of the key, but to no avail. Am I going about this all wrong, or should I not be using the builder?

推荐答案

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

I think this will do what you want. The first two overloads take a map or a collection, and return a composed closure that can be passed to the builder method of the enclosing element to add the contents of the map or collection to the builder.

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

The third is a fallback, and just returns its arguments so they can be passed to the builder method. This handles the strings, but you could also pass it a closure if you want. I replaced the second option element in the map you provided as an example of that.

组合框架 在Groovy 1.8中,所以这在早期版本中不起作用。

ComposedClosure was added in Groovy 1.8, so this won't work in earlier versions.

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

这篇关于如何使用Groovy的MarkupBuilder渲染列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆