February 17, 2020

Groovy Goodness: Parse YAML With YamlSlurper

In Groovy we have useful classes to parse JSON and XML: JsonSlurper and XmlSlurper. Groovy 3 adds the YamlSlurper class to read in YAML formatted strings. The result of parsing the YAML content is a Map object.

In the next example we have a sample YAML as string that we parse using the parseText method of YamlSlurper:

import groovy.yaml.YamlSlurper

def configYaml = '''\
application: "Sample App"
- name: "mrhaki"
  - Groovy
  - Clojure
  - Java
- name: "Hubert"
  - Apples
  - Bananas
- "WS1"
- "WS2"

// Parse the YAML.
def config = new YamlSlurper().parseText(configYaml)

assert config.application == 'Sample App'

assert config.users.size() == 2
assert config.users[0] == [name: 'mrhaki', likes: ['Groovy', 'Clojure', 'Java']]
assert config.users[1] == [name: 'Hubert', likes: ['Apples', 'Bananas']]

assert config.connections == ['WS1', 'WS2']

We can also use Reader with the parse method of YamlSlurlper:

// Create YAML file.
def yamlFile = new File("sample.yml")
// with YAML contents.
sample: true
Groovy: "Rocks!"

// Using File.withReader, 
// so reader is closed by Groovy automatically.
yamlFile.withReader { reader ->
    // Use parse method of YamlSlurper.
    def yaml = new YamlSlurper().parse(reader)
    assert yaml.sample
    assert yaml.Groovy == 'Rocks!'

Finally we need to do an extra step if we want to read in a multiple YAML documents defined in one string or file. The underlying parser of YamlSlurper only reads in one document. A simple workaround is to remove the document separator (---) before parsing the YAML:

def multiDocYaml = '''\
version: 1
loadAtStartup: true

// For YAML with multiple documents separated by ---
// we first need to remove the separators, otherwise
// only the first document is parsed.
def multiDoc = new YamlSlurper().parseText(multiDocYaml.replaceAll('---', ''))

assert multiDoc.version == 1
assert multiDoc.loadAtStartup

Written with Groovy 3.0.0.