Search

Dark theme | Light theme
Showing posts with label GroovyGoodness:YAML. Show all posts
Showing posts with label GroovyGoodness:YAML. Show all posts

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"
users:
- name: "mrhaki"
  likes: 
  - Groovy
  - Clojure
  - Java
- name: "Hubert"
  likes:
  - Apples
  - Bananas
connections: 
- "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.
yamlFile.write('''\
---
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.

February 14, 2020

Groovy Goodness: Create YAML With YamlBuilder

Groovy 3 adds the YamlBuilder class to create YAML output using a Groovy syntax. The YamlBuilder is closely related to JsonBuilder that is described in a previous post. We define a hierarchy using a builder syntax where we can use primitive types, strings, collections and objects. Once we have build our structure we can use the toString() method to get a string representation in YAML format.

In the following example we use YamlBuilder to create YAML:

import groovy.yaml.YamlBuilder

// Sample class and object to transform in YAML.
class User { String firstName, lastName, alias, website }
def userObj = new User(firstName: 'Hubert', lastName: 'Klein Ikkink', alias: 'mrhaki', website: 'https://www.mrhaki.com/') 


// Create YamlBuilder.
def config = new YamlBuilder()

config {
    application 'Sample App'
    version '1.0.1'
    autoStart true
    
    // We can nest YAML content.
    database {
        url 'jdbc:db//localhost'    
    }
    
    // We can use varargs arguments that will
    // turn into a list.
    // We could also use a Collection argument.
    services 'ws1', 'ws2'

    // We can even apply a closure to each
    // collection element.
    environments(['dev', 'acc']) { env ->
        name env.toUpperCase()
        active true
    }

    // Objects with their properties can be converted.
    user(userObj)
}

assert config.toString() == '''\
---
application: "Sample App"
version: "1.0.1"
autoStart: true
database:
  url: "jdbc:db//localhost"
services:
- "ws1"
- "ws2"
environments:
- name: "DEV"
  active: true
- name: "ACC"
  active: true
user:
  firstName: "Hubert"
  alias: "mrhaki"
  lastName: "Klein Ikkink"
  website: "https://www.mrhaki.com/"
'''

Written with Groovy 3.0.0.