What you'll learn

  • Parsing JSON with JsonSlurper and navigating it
  • Building and pretty-printing JSON with JsonOutput
  • Reading XML elements and attributes with XmlSlurper
  • Generating XML with MarkupBuilder

JSON and XML are the languages integrations speak. Groovy makes both feel native: parsed documents become maps, lists and node trees you navigate with dots, and builders let you write output that mirrors its structure.

Parse JSON

import groovy.json.JsonSlurper

def order = new JsonSlurper().parseText(text)    // or .parse(file / inputStream, 'UTF-8')
order.customer.name                               // Acme
order.lines*.sku                                  // [AX-200, BX-310]
order.lines.sum { it.qty * it.price }             // 284.00

JSON objects become maps, arrays become lists, numbers become Integer/BigDecimal — so everything from lists and maps and collection methods just works.

Build JSON

import groovy.json.JsonOutput

def payload = [
    externalId: order.orderId,
    entity    : [name: order.customer.name],
    items     : order.lines.collect { [item: it.sku, quantity: it.qty, rate: it.price] }
]
String json = JsonOutput.toJson(payload)          // compact, for sending
println JsonOutput.prettyPrint(json)              // readable, for logs

Reshaping one JSON structure into another — the heart of most API integrations — is usually just collect and a map literal. (groovy.json.JsonBuilder offers a builder-style alternative.)

Parse XML

import groovy.xml.XmlSlurper

def root = new XmlSlurper().parseText(xml)
root.@id                                          // an attribute
root.Customer.text()                              // an element's text
root.Line.collect { "${it.@sku} x ${it.@qty}" }   // every <Line>
root.Line.findAll { it.@qty.toInteger() > 5 }
root.'**'.findAll { it.name() == 'Line' }         // search at any depth

Note: In Groovy 2.x, XmlSlurper and MarkupBuilder live in groovy.util and groovy.xml; from Groovy 3 onwards use groovy.xml.XmlSlurper. Check your platform’s Groovy version if an import fails.

Build XML

import groovy.xml.MarkupBuilder

def out = new StringWriter()
new MarkupBuilder(out).Invoice(number: 'INV-7731') {
    Customer(order.customer.name)
    order.lines.each { l -> Item(sku: l.sku, qty: l.qty) }
}
println out

Method names become element names, named arguments become attributes, and nesting follows the closures — a nice example of the delegate-based DSLs from the advanced closures lesson.

The full example

// json_xml.groovy — parse and build JSON and XML.
import groovy.json.JsonOutput
import groovy.json.JsonSlurper
import groovy.xml.MarkupBuilder
import groovy.xml.XmlSlurper

// ---- JSON: parse
def text = '''{"orderId": "PO-4471", "customer": {"name": "Acme"},
              "lines": [{"sku": "AX-200", "qty": 24, "price": 8.50},
                        {"sku": "BX-310", "qty": 2,  "price": 40}]}'''
def order = new JsonSlurper().parseText(text)
println order.customer.name                                   // Acme
println order.lines*.sku                                      // [AX-200, BX-310]
println order.lines.sum { it.qty * it.price }                 // 284.00

// ---- JSON: build
def payload = [
    externalId: order.orderId,
    entity    : [name: order.customer.name],
    items     : order.lines.collect { [item: it.sku, quantity: it.qty, rate: it.price] }
]
println JsonOutput.prettyPrint(JsonOutput.toJson(payload))

// ---- XML: parse
def xml = '''<Order id="PO-4471">
  <Customer>Acme</Customer>
  <Line sku="AX-200" qty="24"/>
  <Line sku="BX-310" qty="2"/>
</Order>'''
def root = new XmlSlurper().parseText(xml)
println root.@id                                               // PO-4471 (attribute)
println root.Customer.text()                                   // Acme
println root.Line.collect { "${it.@sku} x ${it.@qty}" }        // [AX-200 x 24, BX-310 x 2]
println root.Line.findAll { it.@qty.toInteger() > 5 }.size()   // 1

// ---- XML: build
def out = new StringWriter()
new MarkupBuilder(out).Invoice(number: 'INV-7731') {
    Customer(order.customer.name)
    order.lines.each { l -> Item(sku: l.sku, qty: l.qty) }
}
println out

For JSON inside Boomi specifically — reading documents from dataContext, splitting and merging — see Working with JSON in Groovy (Boomi).

Try it yourself

Parse '{"items":[{"sku":"AX-200","qty":0},{"sku":"BX-310","qty":4}]}' and output JSON containing only items with stock, as {"inStock":["BX-310"]}.

Show a solution
import groovy.json.JsonOutput
import groovy.json.JsonSlurper

def data = new JsonSlurper().parseText('{"items":[{"sku":"AX-200","qty":0},{"sku":"BX-310","qty":4}]}')
println JsonOutput.toJson([inStock: data.items.findAll { it.qty > 0 }*.sku])
// {"inStock":["BX-310"]}

Key takeaways

  • JsonSlurper turns JSON into maps and lists; JsonOutput turns them back.
  • XmlSlurper navigates XML with dots, @attributes and text().
  • MarkupBuilder writes XML whose code mirrors its structure.
  • Reshaping data is mostly collect plus map literals.

Example files