まえがき
この記事では、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. で動作確認しています。