ray
ray

Reputation: 4250

Groovy convert XML to JSON Array

This is my XML

<ErrorMessage>
   <Code>BUSINESS_EXCEPTION</Code>
   <Message>Invalid postcode - Invalid state</Message>
   <ExtendedStatus>
      <Code>48</Code>
      <Message>Invalid Postcode</Message>
   </ExtendedStatus>
   <ExtendedStatus>
      <Code>12</Code>
      <Message>Invalid State</Message>
   </ExtendedStatus>
</ErrorMessage>

Trying to convert it to following JSON

{
   "code": "BUSINESS_EXCEPTION",
   "message": "Invalid postcode - Invalid state",
   "extendedMessages": [
      {
         "code": "48",
         "message": "Invalid Postcode"
      },
      {
         "code": "12",
         "message": "Invalid State"
      }
   ]
}

I am trying to use following code but it's not generating the expected result:

def toJsonBuilder(xml){
    def pojo = build(new XmlParser().parseText(xml))
    new groovy.json.JsonBuilder(pojo)
}
def build(node){
    if (node instanceof String){ 
        return // ignore strings...
    }
    def map = ['name': node.name()]
    if (!node.attributes().isEmpty()) {
        map.put('attributes', node.attributes().collectEntries{it})     
    }
    if (!node.children().isEmpty() && !(node.children().get(0) instanceof String)) {
        map.put('extendedMessages', node.children().collect{build(it)}.findAll{it != null})
    } else if (node.text() != ''){

        map.put('message', node.text())
    }
    map
}
toJsonBuilder(xml1).toPrettyString()

Upvotes: 0

Views: 289

Answers (1)

cfrick
cfrick

Reputation: 37073

For such a simple format, I'd only pick the attributes you are interested and transform it. Your example seems not to show any irregularities, that would make me do more defensive stuff like checking for text nodes etc.

E.g. have one function to build a "code + message" map. Then iterate the ExtendedStatus nodes and collect with the same function:

def codeAndMessage(node) {
    [code: node.Code.text(),
     message: node.Message.text()]
}

def build(node){
    codeAndMessage(node) +
    [extendedMessages: node.ExtendedStatus.collect{ codeAndMessage it }]
}

Upvotes: 1

Related Questions