Groovy>嵌套的XMLMap

s4n0splo  于 2022-11-01  发布在  其他
关注(0)|答案(2)|浏览(156)

我想在Groovy中将我的Map对象转换为Xml。我看了一下当前的示例,我认为这会简单得多!
我找到的所有样本,要么使用a MarkupBuilder to manually specify the fields,要么使用have a utility methoditerate over the tree。太可恶了!
有什么我错过了吗?我可以很简单地转换这些其他格式...

JsonOutput.prettyPrint(JsonOutput.toJson(map))    // json
(map as ConfigObject).writeTo(new StringWriter()) // groovy
new Yaml().dump(map, new StringWriter())          // yml

为什么我就不能做呢?

XmlUtil.serialize(map)

(OR如何将Map对象转换为Element/Node/GPathResult/Writable对象?)

Groovy示例代码

def myMap = [
    key1: 'value1',
    key2: 'value2',
    key3: [
        key1: 'value1',
        key2: 'value2',
        key3: [
            key1: 'value1',
            key2: 'value2',
        ]
    ]
]

首选输出

<root>
    <key1>value1</key1>
    <key2>value2</key2>
    <key3>
        <key1>value1</key1>
        <key2>value2</key2>
        <key3>
            <key1>value1</key1>
            <key2>value2</key2>
        </key3>
    </key3>
</root>
dluptydi

dluptydi1#

您可以执行:

import groovy.xml.*

new StringWriter().with { sw ->
    new MarkupBuilder(sw).with {
        root { 
            myMap.collect { k, v ->
                "$k" { v instanceof Map ? v.collect(owner) : mkp.yield(v) }
            }
        }
    }
    println sw.toString()
}

要输出:

<root>
  <key1>value1</key1>
  <key2>value2</key2>
  <key3>
    <key1>value1</key1>
    <key2>value2</key2>
    <key3>
      <key1>value1</key1>
      <key2>value2</key2>
    </key3>
  </key3>
</root>

据我所知,没有可以调用的神奇方法(可能是因为属性的原因,没有可以在不知道所需输出结构的情况下完成的神奇Map-〉xml转换)

1aaf6o9v

1aaf6o9v2#

其他可能的解决方案(这也适用于列表结构)...

结构

def myMap = [
    key1: 'value1',
    key2: 'value2',
    key3: [
        key1: 'value1',
        key2: 'value2',
        key3: [
            key1: 'value1',
            key2: 'value2',
        ],
        key4: [
            [ k1: true, k2: 123 ],
            [ k1: false, k2: 456 ]
        ]
    ]
]

代码

def parseNodes( StringBuilder b, node ){
    if ( node instanceof Map ){
        for ( def e in node ){
            def valuesAsList = e.value instanceof List ? e.value : [ e.value ]
            for ( def nodeElement : valuesAsList ){
                b.append( "<${e.key}>" )
                parseNodes(b, nodeElement)
                b.append( "</${e.key}>" )
            }
        }
    } else if ( node instanceof String ){
        def nodeText = groovy.xml.XmlUtil.escapeXml( node.toString() )
        b.append( nodeText )
    } else if ( node instanceof Number || node instanceof Boolean ){
        b.append( node.toString() )
    } else {
        throw new RuntimeException( "Xml parse failed, type " + node.getClass() + " value " + node )
    }
}

def objectToXml( object ){
    def b = new StringBuilder()
    b.append( "<root>" )
    parseNodes(b, object)
    b.append( "</root>" )
    return b.toString()
}

def xml = objectToXml( myMap )
println "Xml result -> " + xml

结果

<root>
    <key1>value1</key1>
    <key2>value2</key2>
    <key3>
        <key1>value1</key1>
        <key2>value2</key2>
        <key3>
            <key1>value1</key1>
            <key2>value2</key2>
        </key3>
        <key4>
            <k1>true</k1>
            <k2>123</k2>
        </key4>
        <key4>
            <k1>false</k1>
            <k2>456</k2>
        </key4>
    </key3>
</root>

...但是,我想建议使用像Jackson这样的库,这种库比手动创建XML更好。

相关问题