Skip to content

ガイド

コードでYAMLをJSONに変換

変換をブラウザのタブではなくスクリプトやビルドステップで行いたいとき、これがその対応物です。

著者 yamltojsonfree · 公開日 · 更新日

Python、Node.js、Go、コマンドライン

各スニペットは input.yaml を読み、整形されたJSONを出力します。ただし互換ではありません — それぞれの下の注記が、そのライブラリがどのYAMLバージョンを実装しているかを示しており、その違いはデータを静かに変えうるのです。

Python

import json, yaml

with open("input.yaml") as f:
    data = yaml.safe_load(f)          # safe_load, never load()

print(json.dumps(data, indent=2))

PyYAMLはYAML 1.1を実装しているため、ここでは no がFalseになります — デフォルトで1.2を使うブラウザ版ツールとは異なります。

Node.js

import { readFileSync } from "node:fs";
import { load } from "js-yaml";

const data = load(readFileSync("input.yaml", "utf8"));
console.log(JSON.stringify(data, null, 2));

js-yaml v5のデフォルトはYAML 1.2 — このサイトのブラウザ版ツールと同じエンジン、同じデフォルトです。

Go

import (
    "encoding/json"
    "os"
    "sigs.k8s.io/yaml"
)

in, _ := os.ReadFile("input.yaml")
out, _ := yaml.YAMLToJSON(in)
os.Stdout.Write(out)

sigs.k8s.io/yamlはJSONタグ経由で変換します。Kubernetes自身が使っている方法です。

Bash (yq)

# Single document
yq -o=json input.yaml

# Multi-document into a JSON array
yq -o=json -I=2 'select(document_index >= 0)' -N input.yaml

# Minified
yq -o=json -I=0 input.yaml

これはmikefarah/yqです。もう一方のyq(kislyuk)はjqのラッパーでフラグが異なります。

スクリプトで正しくやるべき3つのこと

安全なローダーを使う。 Pythonでは、ローダーを明示しない yaml.load() はタグ付きYAMLから任意のPythonオブジェクトを構築できます — 入力が自分のものでなければ、それはコード実行です。safe_load() はプレーンなデータだけを解析し、他を使う理由はほぼありません。

YAMLのバージョンを知る。 PyYAMLはYAML 1.1を読むため country: NO は False になります。js-yaml v5とGoのKubernetes系パーサーは1.2を読むため、同じ行は文字列のままです。あるライブラリで変換し別のライブラリで検証するパイプラインは、自己矛盾しうるのです。影響を受ける値の完全な一覧はYAML 1.1と1.2の違いのガイドにあります。

マルチドキュメントストリームを扱う。 KubernetesとHelmの出力は通常 --- で区切られた複数のドキュメントです。素の load は最初の1つだけを読み、残りを黙って捨てます — Pythonでは yaml.safe_load_all()、js-yamlでは loadAll()、あるいは上に示したyqの呼び出しを使えば、すべてのドキュメントが得られます。

あるいはスクリプトを書かない

1回きりの変換なら、無料のYAML→JSON変換ツールが上記のすべてをブラウザ内で行います:マルチドキュメントストリーム、アンカーとマージキー、YAML 1.1と1.2モード、正確な行に固定されたエラー。アップロードは一切なく、パーサーは完全にあなたの端末内で動きます。

参考資料