JSON から YAML への変換
JSON を YAML に変換し、追加した引用符ごとに理由を説明 — 引用符がなければ静かに真偽値や数値や日付になる文字列を示します。
name: deploy
country: 'NO'
startsAt: '12:30'
mode: '0755'
version: '1.10'
released: '2024-01-30'
enabled: 'yes'
script: |-
set -e
npm run build
npm test
replicas: 3
tags:
- web
- edge
引用符で囲まれた値: 6 個。 YAML 1.1 でのみ必要なもの: 4 個。上のスキーマを切り替えると違いが分かります。
country1.1 のみ「NO」は真偽値の false として読まれてしまいます。
startsAt1.1 のみ「12:30」は 60 進数として 750 と読まれてしまいます。
mode「0755」は先頭が 0 のため、数値の 493 として読まれてしまいます。
version「1.10」は数値の 1.1 として読まれてしまいます。
released1.1 のみ「2024-01-30」はテキストではなく日付として読まれてしまいます。
enabled1.1 のみ「yes」は真偽値の true として読まれてしまいます。
このツールの役割
JSON 文書を YAML に変換し、それから各文字列がなぜ引用符に収まったかを教えます。その二つ目の部分がツールの存在理由です: ほかのすべての変換器は出力を返し、あなたの値の一つがもう文字列でないことを後で見つけさせます。
変換は一方向に動きます。YAML を読むことはそれを書くよりずっと大きな問題で、部分的に正しい YAML パーサーはまったくないより悪いです — ファイルを受け付け、文句を言わずに誤ったデータを返します。出力は境界があるので、それがここで覆われる方向です。
なぜ変換器に見解が要るのか
JSON はすべてが何の型かを言います。文字列は引用符を持ち、数値は持たず、三つ目の可能性はありません。YAML は代わりに、引用符のない値の型をその形を見て決めます: 真偽値のパターンに合えば真偽値、数値に合えば数値、何にも合わなければ初めてテキストとして残ります。
それが YAML を手で書いて心地よくするものであり、それへの変換を判断の要ることにするものです。入力のすべての文字列が、YAML が解決するすべてのパターンに対して確認され、合えば引用符が付けられねばなりません。安全な方向で誤ると出力がうるさくなり、もう一方の方向で誤ると値が黙って型を変えます。
ノルウェー問題と、その親戚
最もよく知られた場合は国コードの一覧です。ノルウェーは NO で、YAML 1.1 では引用符のないトークン NO は真偽値の false です。国を列挙する設定ファイルがノルウェーを失い false を得て、どこでも何もエラーを報告しません。
それは一つの奇妙な規則ではなくその一族です。YAML 1.1 は y・Y・yes・no・on・off のすべてを、あらゆる大文字化で真偽値として読み、化学記号・スイッチの位置・問いへの答えを捕らえます。そして数値の解決器はさらに奇妙です:
- 12:30 は 750 です。YAML 1.1 はコロン区切りの数字を 60 進数として読むので、時刻や時間の長さが整数になります。
- 0755 は 493 です。先頭のゼロは YAML 1.1 で 8 進数を意味し — YAML 1.2 では同じテキストが 10 進数の 755 なので、二つの版はどちらの数かで食い違い、どちらであるかではありません。
- 1.10 は 1.1 です。二部構成のバージョン番号は浮動小数点で、末尾のゼロが消えます。1.10 に固定された依存関係が今や 1.1 を指します。
- 2024-01-30 は文字列ではなく日付オブジェクトです。YAML 1.1 がタイムスタンプ型を持つからです。
- 空の文字列は null で、素の語 null・Null・NULL とチルダも同じです。
これらのどれも YAML のバグではありません。解決器が、たまたま合うテキストに対して、約束どおりのことをしているのです。唯一の防御は合うものを何でも引用符で囲むことで、それがこのツールがすることであり、findings パネルが一行ずつ説明することです。
二つの版と、なぜ古いほうが既定なのか
YAML 1.2 は 2009 年に到着し、驚きの解決器のほとんどを取り除きました。そのコアスキーマは true と false だけを真偽値として保ち、60 進数をまるごと落とし、タイムスタンプ型を持ちません。1.2 では NO も 12:30 も 2024-01-30 もすべてただの文字列です。
落とし穴は、実際にあなたのファイルを読むものです。PyYAML は YAML 1.1 を実装し、PyYAML は膨大な量のツール — Ansible、古い Kubernetes クライアント、無数のスクリプト — の背後のパーサーです。Go の yaml.v3 と現行の js-yaml は 1.2 に従います。だから同じ文書が、誰が開くかによって二つの異なるふうに読まれえて、どこでも安全な唯一の出力は 1.1 向けに引用符を付けたものです。
それがここの既定です。設定を 1.2 に切り替えても何も隠しません — 新しい解決器で再出力し、findings パネルが縮むので、どの引用符が古いスキーマのためにあったかを正確に見られます。残るものが、すべてのパーサーが必要とするものです。
型ではなく構文を壊す文字列
二つ目の文字列の集まりが別の理由で引用符を要します: YAML がそれらを別の型として読むからではなく、そもそもテキストとして解析されないからです。
- 空白が続くコロンはキーを終わらせます。「note: time: now」は、値がキー「time」であるキー「note」として読まれるでしょう。
- ハッシュが続く空白はコメントを始めるので、その後のすべてが消えます。
- 先頭の -・?・:・[・]・{・}・#・&・*・!・|・>・%・@ やバッククォートは指示文字で、構造的な何かを意味します。
- 先頭や末尾の空白は引用符のない値に保たれないので、" x " は "x" として返ってきます。
- 値のどこかのタブはただちに拒否されます — PyYAML は誤読するのではなく文書全体を拒むので、これは大声で失敗します。
単一引用符は足りるところではどこでも使われます。ちょうど一つのエスケープ規則 — アポストロフィは二度書く — を持ち、二重引用符が持ち込むバックスラッシュのエスケープより読みやすいからです。二重引用符は、本当にエスケープが要る場合のために取ってあります: 制御文字、タブ、そしてブロックを使えない複数行の文字列です。
複数行の文字列とチョンピング指示子
改行を含む文字列 — スクリプト、証明書、散文の塊 — が、そもそも誰かが YAML を欲しがる理由であることが多いです。JSON はそれを、とても長い一行にバックスラッシュ n のエスケープでしか書けません。YAML はリテラルのブロックスカラーを持ち、パイプで導入され、そこではテキストが下にインデントされて読める形で現れます。
微妙なのは末尾の改行に何が起きるかで、それはチョンピング指示子で制御されます:
- 素のパイプはクリップします: ブロックが末尾の改行をいくつ持っても、値はちょうど一つを得ます。
- マイナスが続くパイプはストリップします: 値は一つも得ません。
- プラスが続くパイプはキープします: 値はそのすべてを得ます。
このツールは与えられた文字列から指示子を選ぶので、値は往復を正確に生き延びます。知っておく価値があるのは、既定 — 素のパイプ — が人が手で書くもので、二つの改行やゼロの改行で終わった文字列を黙って正規化するからです。
ブロックスカラーはすべてを運べず、運べないところでは出力が二重引用符に退き、findings パネルがなぜかを言います。復帰は生き残りません。ブロックスカラーが改行を正規化するからです。空白で始まる最初の行は余分なインデントとして読まれ剥がされるでしょう。そして空白で終わる行は仕様では保たれますが画面では見えず、ほとんどのエディターが保存時に取り除くので、それを引用符で囲むのがより安全な選択です — それは限界ではなく決定で、そう報告されます。
複数の文書
YAML は JSON が持たないものを持ちます: ファイルが三つのダッシュで分けられた文書の流れを保持できます。それが Kubernetes マニフェストの形式で、JSON 配列がしばしば YAML シーケンス以外の何かになる必要がある理由です。
ここのスイッチはトップレベル配列の各要素を独自の文書として出力します。そして入力がまったく単一の JSON 値ではなく、すべての行がそれぞれ解析されるとき、それは NDJSON — ログや API エクスポートが届く行区切りの形式 — として読まれ、各行が文書になります。その読みは推測なので、黙ってではなく出力の上に報告されます。
その退避は、入力全体が解析に失敗し、すべての行が成功するときにだけ当てはまり、単に不正なだけの文書はそうしません。構文エラーは今も構文エラーとして、それが起きた行と列とともに現れます。
変換が保てないもの
二つのものが、このツールがあなたのデータを見る前に、両方とも JSON の解析そのもので失われ、どちらかを知る価値があります。
重複するキー。JSON はオブジェクトが同じキーを二度並べるのを許し、ほとんどのパーサーは黙って最後を保ちます。YAML は重複をまったく禁じるので、出力は有効ですが、より早い値は既に消えています — そして変換器は決して受け取らなかったものを報告できません。
整数の精度。約 9000 兆より大きな JSON 数値は倍精度に解析されるのを生き残らないので、12345678901234567890 のような ID は丸められて返ってきます。これは YAML の問題ではなく、このツールが持ち込む問題でもありません。この言語のすべての JSON パーサーで起きます。大きな識別子が重要なら、両側で文字列に属します。
出力についての注記
インデントは常にスペースです。YAML がインデントのタブをまったく禁じるからで — それは形式が厳格である数少ないことの一つです。スペース 2 個が慣習で、4 個は一部のハウススタイルが欲しがるので提供されます。
シーケンスはそのキーの下にインデントされます。それもインデントのない形も合法な YAML で同じことを意味します。インデントされたほうが、ほとんどの人が書き、ほとんどのエディターが正しく畳むものです。
空の配列やオブジェクトは、括弧か波括弧の対としてフロースタイルで書かれます。ブロックスタイルには空を表す術がないからで — 続く行に書くものが何もありません。
出力は改行で終わり、それは几帳面さではなく荷重を担います。ブロックスカラーのチョンピングはそれに続く改行に対して測られるので、最後の改行のないファイルのまさに末尾のクリップされたブロックは、保つはずだった改行を失います。
よくある質問
- JSON は既に有効な YAML ですか?
- YAML 1.2 では、はい: 仕様がそう明言し、1.2 パーサーは JSON ファイルを直接読みます。実務ではあまり役立ちません。変換する理由は読みやすさ — コメント、ブロックスカラー、波括弧なし — で、JSON を YAML ファイルに貼り付けてもそのどれも得られないからです。YAML 1.1 ではまったく真ではなく、それが二つの版を見分ける価値のあるもう一つの理由です。
- 私の文字列が、要らなそうな引用符を得たのはなぜですか?
- ほぼ確実に要ります。YAML は引用符のない値をパターンの照合で型付けするので、NO・yes・off・12:30・0755・1.10・2024-01-30 と空の文字列がすべて文字列でなくなります。findings パネルはそれぞれを名付け、それがなっていた値を示すので、信じるのではなく主張を確認できます。YAML 1.2 パーサーを狙うなら、スキーマを切り替えると 1.1 だけが要るものが取り除かれます。
- ここでの YAML 1.1 と 1.2 の違いは何ですか?
- 1.2 は驚きのほとんどを引き起こす解決器を落としました: yes/no/on/off はもう真偽値でなく、60 進数はなくなり、タイムスタンプ型はありません。PyYAML は 1.1 を実装し今もいたるところにあるので、保守的な出力が既定です。1.2 の設定は、何がファイルを読むか分かっているときのためにあります。
- YAML を JSON に戻せますか?
- いいえ、意図的に。YAML の読み手はアンカー・エイリアス・タグ・マージキー・五つのスカラースタイル・二つのスキーマ版を要し、そのどれかを微妙に誤ると、ファイルを受け付けて含まれていたのと違うデータを返すことになります。その失敗は静かで、それが機能を提供しないより悪くします。
- Kubernetes 形式の複数文書ファイルをどう得ますか?
- トップレベル配列の各要素を独自の文書として出力するスイッチをオンにすると、配列が三つのダッシュで分けられた文書になります。入力が代わりに NDJSON — ログや API エクスポートがしばしばそうであるように、一行に一つの JSON オブジェクト — なら、それは自動的に検出され出力の上に報告されます。
- 出力にコメントがないのはなぜですか?
- 入力になかったからです。コメントは YAML が持ち JSON が欠く主なもので、変換器はそれをでっち上げられません。これはもう一方の向きでも覚えておく価値があります: YAML ファイルを JSON で往復させると、その中のすべてのコメントが消えます。
- 私が貼り付けたものはサーバーに送られますか?
- いいえ。解析と変換はすべてブラウザ内で動きます。何もアップロードも記録もされず、ネットワーク接続なしで動きます。