JSONをYAMLに変換
JSONからYAMLへの変換は、ドキュメントをブラウザ内でYAMLに変換し、出力をパースして読み戻すことでその結果を検証します。この仕組みを支えるルールは次のとおりです。そのまま書くと別のものに解決されてしまう文字列は、常にクォートで囲まれる——したがって文字列"no"は引用符を保ち、"007"、"null"、"12:30"も同様です。
JSONをYAMLに変換はどう動きますか?
JSONからYAMLへの変換は、簡単な方向のように思えます——YAMLはスーパーセットなので、すべてのJSONドキュメントはすでに有効なYAMLです。それは事実ですが、求められている仕事ではありません。仕事は、人が読みたいと思うYAMLを生成すること、つまりフロースタイルではなくブロックスタイルで出力することです。そしてそこに正しさの問題が現れます。
クォートは見た目を飾るためのものではない
YAMLはクォートされていないスカラーをパターンで解決します。文字列noを引用符なしで書くと、YAML 1.1のリーダーはブール値falseとして読み込みます。007と書けば数値7になります。null、true、12:30、0x1f、.infと書けば、いずれも文字列ではない何かとして読み戻されます。
そこでエミッタは解決ルールを逆向きに実行します。そのまま書くとその文字列以外の何かに解決されてしまう場合、文字列はクォートで囲まれます。1.2では解決が変わらないのに1.1では変わってしまうトークンもクォートします。どこで読まれても同じ意味になるべきだからです。これが、一見不要に見える箇所まで結果に引用符が付く理由です——どれ1つとして無駄な引用符はありません。
ラウンドトリップは主張ではなく、実際に検証されます
すべての変換はパースして読み戻され、元のJSONと比較され、その結果は統計バーに表示されます。クォートのルールに1つでも漏れがあると、それこそがもっともらしい出力と壊れた設定ファイルを生む種類のバグです。だから検証はテストスイートの中だけでなく、あなたのドキュメントそのものに対して実行されます。
複数行文字列はブロックスカラーになる
改行を含む文字列は|ブロックとして書かれます。証明書やスクリプト、SQLをJSONではなくYAMLに入れる理由がまさにこれです。JSONではPEM鍵は\nエスケープの並ぶ、読めない1行になります。chompingインジケータはデータに合わせて選ばれ、文字列が改行で終わっていれば|、終わっていなければ|-となるため、末尾のバイトまで保持されます。
キーは値と同じルールでクォートされる
キーもまたスカラーです。y: 2は1.1のリーダーでは{True: 2}として読み込まれます。そしてon:——すべてのGitHub Actionsワークフローに現れる2番目のキー——が最もよく知られた例です。キーは値と同じ扱いを受けるため、"on"はクォートされた状態で出力されます。
JSON
{
"regions": ["NO", "SE"],
"build": "007",
"enabled": true
}YAML
regions: - "NO" - "SE" build: "007" enabled: true
JSONをYAMLに変換が対応するオプションとエッジケースは?
| パラメータ | 型 | デフォルト | 動作とエッジケース |
|---|---|---|---|
| インデント | スペース | 2 | インデントあたりのスペース数。YAMLはインデントにタブを完全に禁止しているため、これは文字数ではなくカウントです。 |
| シーケンスのインデント | 真偽値 | off | オフの場合、リストのダッシュは親キーの列に配置され、これは手書きのKubernetesマニフェストのように見えます。オンの場合、それらは1レベルインデントされ、これはほとんどのライブラリが出力する形式です。両方とも有効です。 |
| キーのソート | 真偽値 | off | ドキュメント順ではなくアルファベット順に並べ替えます。異なる順序で書かれた2つの設定を比較するのに便利です。 |
| ドキュメント開始 | 真偽値 | off | ---マーカーを出力します。Kubernetesマニフェストのように通常、複数のドキュメントを1つのファイルに連結する場合に必要です。 |
| あいまいな文字列 | クォート | 常に | no, yes, on, off, y, n, true, null, ~, 007, 12:30, 0x1f, .inf, 空文字列。これらはいずれも、そのまま書くと非文字列として解釈されます。 |
| 複数行文字列 | ブロックスカラー | on | |ブロックとして書き出され、文字列の末尾に改行があるかどうかに応じてchompingインジケータが一致するため、バイトが追加または失われることはありません。 |
| 空コンテナ | []と{} | 明示 | 空の配列またはオブジェクトはフロースタイルで書き出されます。それらを完全に省略すると、空のリストとnullが区別できなくなります。 |
| null | null | null | 単語としてnullと書き出され、空のままにするか~と書くのではなく、それは人が読んでもパーサーが読んでも同じように読めるためです。 |
| ラウンドトリップ | 検証済み | 全変換 | 出力が再びパースされ、入力と比較されます。結果は想定されるのではなく、ステータスストリップに報告されます。 |
よくある質問
普通の文字列に引用符が付くのはなぜですか?
そのまま書くと別のものに解決されるからです。"no"はYAML 1.1のリーダーではブール値falseになり、"007"は数値7に、"12:30"は六十進法の数値に、"null"はnullになってしまいます。値を文字列として保っているのは引用符だけで、そのことは統計バーのラウンドトリップ検証が、実際のドキュメントを使って確認してくれます。
YAMLは本当にJSONより小さくなりますか?
たいていはそうです。統計バーに、あなたのドキュメントでの数値が表示されます。波括弧、角括弧、キーを囲む引用符をなくすだけで、設定ファイルは意外なほど縮みます。ただしYAMLがJSONから得られるものはサイズではありません——JSONにはまったく表現手段のないコメントと、読める形の複数行文字列です。
コメントを取り戻すことはできますか?
できません。どんなツールにもできません。JSONにはコメントが存在しないので、ドキュメントがJSONになった時点でコメントはすでになく、入力には復元すべきものが残っていません。YAMLファイルを編集しているのなら、YAMLのまま編集してください。JSONへのラウンドトリップはコメントをすべて剥がし、順序も元には戻しません。
リストのスタイルはどちらを使うべきですか?
どちらでも構いません。パース結果は同一です。親キーと同じ桁にダッシュを置くスタイルは、手書きのKubernetesマニフェストやGitHubワークフローで見かける形で、深くネストしたファイルではインデント2桁分の節約になります。ダッシュをインデントするスタイルは、ほとんどのライブラリが出力する形で、社内スタイルで必須としているところもあります。周囲のファイルに合わせて選んでください。
複数行文字列が、JSONのときのようにエスケープされないのはなぜですか?
|ブロックスカラーとして書かれるためです。\nエスケープの代わりに、実際の改行がそのまま保持されます。設定ファイルにYAMLを使う最良の理由がこれです。PEM証明書やシェルスクリプトはYAMLでは読める形のまま、JSONでは3,000文字の1行になってしまいます。chompingインジケータは、文字列が改行で終わっていたかどうかを保持するように選ばれます。
JSONはアップロードされますか?
いいえ。パースも、変換も、検証のラウンドトリップも、すべてブラウザ内で動作します。Networkパネルで確認できます。ここではとりわけ重要です。JSONをYAMLに変換したものは、そのまま設定ファイルになろうとしていることが多く、設定ファイルには接続文字列や鍵が含まれるからです。