「Apache Groovy」- 常用 YAML 操作

该笔记将记录:在 Apache Groovy 中,常用 YAML 操作,以及相关问题处理方法;

SnakeYAML for Groovy 2.4.21

Parsing YAML with SnakeYAML | Baeldung

@Grab(group='org.yaml', module='snakeyaml', version='1.33')
import org.yaml.snakeyaml.Yaml

def yaml = new Yaml()
def inputStream = new FileInputStream("example.yaml")
def data = yaml.load(inputStream)

println(data.person.name)
println(data.person.age)

Loading Multiple Documents

public void whenLoadMultipleYAMLDocuments_thenLoadCorrectJavaObjects() {
    Yaml yaml = new Yaml(new Constructor(Customer.class, new LoaderOptions()));
    InputStream inputStream = this.getClass()
      .getClassLoader()
      .getResourceAsStream("yaml/customers.yaml");

    int count = 0;
    for (Object object : yaml.loadAll(inputStream)) {
        count++;
        assertTrue(object instanceof Customer);
    }
    assertEquals(2,count);
}

YamlSlurper for Groovy 3.0

import groovy.yaml.YamlSlurper

def ys = new YamlSlurper()
def yaml = ys.parseText(yamlString)

assert 'groovy' == yaml.language
assert 'required' == yaml.sudo
assert 'trusty' == yaml.dist
assert ['openjdk10', 'oraclejdk9', 'oraclejdk8'] ==  yaml.matrix.include.jdk
assert ['unset _JAVA_OPTIONS'] == yaml.before_script*.trim()

处理 Multi Document 类型

Doesn’t Groovy 3.0.8 YamlSlurper support multidoc YAML files? – Stack Overflow

yamlContent.split('---').findAll().collect {}

常见问题

Q:unable to resolve class groovy.yaml.YamlSlurper
A:Yamlslurper introduced in groovy v3.0. I think you have lower version of groovy in Jenkins.
R:jenkins – WorkflowScript: 1: unable to resolve class groovy.yaml.YamlSlurper – Stack Overflow

Map/List 转 YAML

import groovy.yaml.YamlBuilder

def yamlBuilder = new groovy.yaml.YamlBuilder()
def result = yamlBuilder([1, 2, 3])

assert result instanceof List
assert yaml.toString() == '''---
- 1
- 2
- 3
'''

构建 YAML 文本

def builder = new YamlBuilder()
builder.records {
    car {
        name 'HSV Maloo'
        make 'Holden'
        year 2006
        country 'Australia'
        homepage new URL('http://example.org')
        record {
            type 'speed'
            description 'production pickup truck with speed of 271kph'
        }
    }
}

assert builder.toString() == '''---
records:
  car:
    name: "HSV Maloo"
    make: "Holden"
    year: 2006
    country: "Australia"
    homepage: "http://example.org"
    record:
      type: "speed"
      description: "production pickup truck with speed of 271kph"
'''

通过 SnakeYaml 模块

对于旧 Groovy 版本,能够使用该类库:

解析 YAML 文件

@Grab(group='org.yaml', module='snakeyaml', version='1.17')
import org.yaml.snakeyaml.Yaml

Yaml yaml = new Yaml()

Map config = yaml.load(new File('config.yaml').text)

Map/List 转 YAML

@Grab(group='org.yaml', module='snakeyaml', version='1.17')
import org.yaml.snakeyaml.Yaml

Yaml yaml = new Yaml()
Map config = [kind: 'Pod', metadata:[name: app]]

assert yaml.dump(config) == '''kind: Pod
metadata:
  name: app
'''

在使用 SnakeYaml 模块时,我们生成的 YAML 内容“异常”,尤其是对象时:

targets: ['172.16.48.251:50057']
labels: {hostname: foo-node}

// 这导致 YAML 解析失败

参考文献

YamlBuilder (Groovy 4.0.0-SNAPSHOT)
The Apache Groovy programming language – Processing YAML
Groovy Goodness: Create YAML With YamlBuilder – JDriven Blog
Groovy Goodness: Create YAML With YamlBuilder – Messages from mrhaki