简体   繁体   中英

Want Groovy MarkupBuilder() Equivalent to JSONBuilder() for Objects

Goal: Given the myInfoObject definition below, I wish to be able to do this:

println new groovy.xml.MarkupBuilder(myInfoObject).toPrettyString()

Premise:
The following is one of the most amazing and convenient features of Groovy for my use cases: Brilliant dynamic serializing of complex nested objects into sensible JSON. Just pass the object, and get the JSON.

Example - A simple Map within a Map

import groovy.json.*

def myInfoMap = [
    firstname : 'firstname',
    lastname : 'lastname',
    relatives : [
        mother : "mom",
        father : "dad"
 ]
]   
myInfoJson = new JsonBuilder(myInfoMap)

//One line, straight to JSON object, no string writer/parser conversions
//Works on any object, extremely elegant, even handles deep nesting
//Alternatively, add .toPrettyString() for the string representation

Returns:

{
    "firstname": "firstname",
    "lastname": "lastname",
    "relatives": {
        "mother": "mom",
        "father": "dad"
    }
}

I have read through all the MarkupBuilder examples and docs I could find, and there does not seem to be any equivalent for XML. Here is the closest I could find, it is not nearly the same. http://www.leveluplunch.com/groovy/examples/build-xml-from-map-with-markupbuilder/

XML and JSON are fundamentally different, but it's still common for objects to be represented by XML in a similar fashion. An XML equivalent would require at least one optional parameter specifying how the data should be represented, but I think a sensible default would be something like:

<myInfoMap>
  <firstname>firstname</firstname>
  <lastname>lastname</lastname>
  <relatives>
    <relative>
      <mother>mom</mother>
    </relative>
    <relative>
      <father>dad</father>
    </relative>
  </relatives>
</myInfoMap>

...Which has to be built manually with intimate knowledge of the structure like so...

def writer = new StringWriter()
def builder = new groovy.xml.MarkupBuilder(writer)

builder.myInfoMap {
    myInfoMap.each{key, value ->
        if (value instanceof Map){
            "${key}"{
                value.each{key2, value2 ->
                    "${key[0..key.size()-2]}"{
                        "${key2}" "${value2}"
                    }
                }
            }
        }else{
            "${key}" "${value}"
        }
    }
}
println writer.toString()

I even tried to be clever and make it a bit dynamic, but you can see how far from the JSONBuilder example it is, even in a simple case.

If this is currently impossible and not on anybody's radar, I will submit my first JIRA ticket to the Groovy project as a feature request. Just want to be sure before I do. Please just comment if you think this is the next step.

Try grails.converters.XML . In your case:

def myInfoMap = [
        firstname: 'firstname',
        lastname : 'lastname',
        relatives: [
                mother: "mom",
                father: "dad"
        ]
]

println new grails.converters.XML(myInfoMap)

would result in:

<?xml version="1.0" encoding="UTF-8"?>
<map>
    <entry key="firstname">firstname</entry>
    <entry key="lastname">lastname</entry>
    <entry key="relatives">
        <entry key="mother">mom</entry>
        <entry key="father">dad</entry>
    </entry>
</map>

Sorry I may be wrong but XmlUtil.serialize I think covers what you want.

MrHaki: groovy-goodness-pretty-print-xml

I did some work a while back that I was going to release as a plugin, I didn't release it in the end. Got side tracked with dns on the fly update which didn't end up working. Anyhow process xml controller and follow gsp view for it . But I think MrHaki has put it a lot more elegantly and has some really good examples

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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