Groovy3 Tips YamlSlurperについて紹介

まえがき

この記事では、Groovy3から追加された。
YamlSlurperについて紹介します。

JsonSlurper, XmlSlurper はすでにありましたが、
Groovy3からは、YamlSlurperというのが新たに追加されました。

またこれと一緒に、YamlBuilderというのも追加されています。

YamlSlurper

他のSlurperと同じく、
YAMLをパースして、Mapオブジェクトにバインドしてくれるものとなります。

Gradle設定

現在 YamlSlurperは、
JsonSlurper, XmlSlurper と違ってデフォルトでバンドルされてないようなので、
利用する場合は別途、 groovy-yaml というのを依存に追加しておく必要があります。

Gradleであれば、
build.gradle の dependencies に下記のように追記しておきましょう。

build.gradle

dependencies {
    // Groovy
    implementation group: 'org.codehaus.groovy', name: 'groovy-all', version: '3.0.5'

    // YamlSlurperを使うために必要 (groovy-allに含まれてないので)
    implementation group: 'org.codehaus.groovy', name: 'groovy-yaml', version: '3.0.5'

    // ...
}

実行サンプル

k8sのYAMLをパースする例を記載しておきます。

YamlSlurperのサンプル

String YAML = """\n
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80
"""

// YAMLのパース
def m = new YamlSlurper().parseText(YAML) as Map

// Mapオブジェクトでアクセスできる
assert m.apiVersion == "apps/v1"
assert m.metadata.labels.app == "nginx"

// Output
m.each { println it }

//==> apiVersion=apps/v1
//==> kind=Deployment
//==> metadata={name=nginx-deployment, labels={app=nginx}}
//==> spec={replicas=3, selector={matchLabels={app=nginx}}, template={metadata={labels={app=nginx}}, spec={containers=[{name=nginx, image=nginx:1.14.2, ports=[{containerPort=80}]}]}}}

YamlSlurper#parseText の代わりに、
YamlSlurper#parse を使えば、直接Fileからパースすることも可能です。

マルチドキュメント

YAMLは、--- でドキュメントを区切ることができます。(マルチドキュメントというもの)

しかし、残念なことにYamlSlurperでは、サポートしていないので、
パースする前にあらかじめ --- でスプリットして、パースしたいドキュメントを選択する必要があります。

マルチドキュメントのサンプル

String YAML = """\n
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  selector:
    app: nginx
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
"""

// あらかじめ `---` で分割
def arr = YAML.split(/(?m)^---\s*$/)

// YAMLのパース (2つ目のドキュメントをパース)
def m = new YamlSlurper().parseText(arr[1]) as Map

// Output
m.each { println it }

//==> apiVersion=v1
//==> kind=Service
//==> metadata={name=nginx-service}
//==> spec={selector={app=nginx}, ports=[{protocol=TCP, port=80, targetPort=80}]}

ちなみに、---でスプリットせずにそのまま渡すと、
YamlSlurperは一つめのドキュメントのみをパースします。


このコードは、Groovy 3.0.5. で動作確認しています。

コメントを残す