Question

I'm trying to parse a large XML file to covert into a JSON document and I'd like to create a method to construct the XmlSlurper find expression, but I'm having trouble with it.

Here is a snippet of the XML:

<site>
  <metrics>
    <ruleScore>
      <avg>89.0</avg>
    </ruleScore>
  </metrics>
</site>

Here is the method:

static def getDecNode(String parentNode String childNode) {
    return data.metrics.parentNode.childNode.find { it.name() == childNode }.toDouble()
}

From there I would call it like:

def root = json {
    type record
    time { $date timestamp }
    data {
        ruleScore {
            avg getDecNode("ruleScore","avg")
        }
    }
}
Was it helpful?

Solution

You can make getDecNode a closure which will allow access to the parsed xml present in the script and then build the json. Also note, the implementation inside the closure (usage of GString):

def xml='''
<site>
  <metrics>
    <ruleScore>
      <avg>89.0</avg>
    </ruleScore>
  </metrics>
</site>
'''

def slurper = new XmlSlurper().parseText(xml)

def getDecNode = {String parentNode, String childNode ->
    slurper.metrics."$parentNode"
                   ."$childNode"
                   .find { it.name() == childNode }
                   .toDouble()
}

//Building JSON
def builder = new groovy.json.JsonBuilder()
builder {
    type 'record'
    time { $date 'timestamp' }
    data {
        ruleScore {
            avg getDecNode("ruleScore","avg")
        }
    }
}

builder.toPrettyString()

Note above, I have assumed JSON element values as Strings, hence 'record', 'timestamp'. They can be replaced as per the requirement.

I cannot foresee the benefit with the separate implementation planning of a method/closure, but I think based on the size of the xml the intention would be different.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top