無料YAMLかJSONコンバーター
YAMLをJSONに即座に変換します。リスト、マップ、アンカーを含むすべてのYAML構文に対応。ブラウザ内で完全に実行されます。
YAMLとは何ですか?
YAML(YAML Ain't Markup Language)は、設定ファイルによく使用される人間に優しいデータシリアライゼーション形式です。インデントとシンプルな構文を使用して、リスト、辞書、スカラー値などのデータ構造を表現します。
なぜYAMLをJSONに変換するのか?
- 普遍的な互換性 · JSONはほぼすべてのプログラミング言語とツールでサポートされています。
- 設定管理 · 多くのツールは設定やデータ交換にJSONを期待します。
- API統合 · ウェブAPIは通常JSON形式を要求します。
- データ処理 · 自動化ワークフローで使用するためにYAML設定ファイルを変換します。
よくある質問
どのYAML機能がサポートされていますか?
このコンバーターは、マップ、リスト、文字列、数値、ブール値、null、複数行文字列、アンカー、エイリアスを含むすべての標準YAML機能をサポートしています。
複雑なYAML構造は正しく変換されますか?
はい。このコンバーターはネストされた構造、オブジェクトのリスト、コメント(削除されます)、そしてすべてのYAML構文を処理します。構文エラーがある場合は、明確なエラーメッセージが表示されます。
YAMLのコメントは保持されますか?
いいえ。コメントはデータ構造の一部ではないため、JSON出力には含まれません。
YAMLの小史:2001年、メーリングリスト発のフォーマット
YAMLの前史はsml-devメーリングリストから始まる。2000年代にxml-devから派生し、人間が編集するデータにXMLは冗長だと考えた人々が集まった場だ。2つの流れが合流した。Ingy döt NetのPerlモジュールData::Denter(Inline Perlモジュール向けのシリアライゼーション形式として書かれたもの)と、Oren Ben-KikiとClark EvansによるXML簡略化を目指した共同研究だ。2001年5月11日、Clark Evansが「YAML Draft 0.1」をsml-devに投稿し、翌日xmlhackの記事でこのフォーマットが初めて公開された。
頭文字語の最初の展開は自嘲的なものだった。Yet Another Markup Language(もう一つのマークアップ言語)という、2001年に乱立していたマークアップフォーマットへの皮肉だ。2001年12月から2002年4月にかけて、著者たちは再帰的なバックロニムYAML Ain't Markup Languageに改めた。YAMLがXMLやHTMLのようなドキュメントマークアップではなくデータシリアライゼーション形式であることを強調するためと、単純に冗談が古くなったためだ。この再帰的展開は今日もyaml.orgの公式タグラインとなっている。
仕様のタイムライン
- Draft 0.1:2001年5月11日、sml-devメーリングリストでの発表。
- YAML 1.0:2004年1月29日、Ben-Kiki・Evans・Ingy döt Netによる最初の安定版仕様。
- YAML 1.1:2005年1月18日、大半の「レガシー」パーサーが今もデフォルトで模倣するバージョン。ノルウェー問題とほとんどの暗黙型付けの問題の発生源。
- YAML 1.2.0:2009年7月21日、「JSONスーパーセット」を明示的な目標に掲げた最初の改訂版。JSONのトークンに合わせて暗黙の型付けを書き直した。
- YAML 1.2.1:2009年10月1日、1.2.0の正誤表のみを更新したリフレッシュ版。
- YAML 1.2.2:2021年10月1日、2020年に発足した新YAML言語開発チームによる正誤修正版。
1.2.2仕様は「YAML仕様v1.2から規範的な変更はない」と明記している。作業内容はソースをDocBookからMarkdownへ変換し、プレーンテキストのLaTeXから図を再生成し、外部コントリビューターが仕様に対してプルリクエストを送れるよう開発プロセスを開放することだった。2009年以降、新しい言語機能は追加されていない。それ以降のパーサー適合性バグはすべて、1.1からの名残か、現在15年以上続く仕様からの逸脱だ。公式MIMEタイプapplication/yamlは2024年に確定した。ファイル拡張子.yamlと.ymlはどちらも2006年頃から認められており、.yamlが推奨されている。
JSONとの関係:「ほぼスーパーセット」
YAML 1.2.2仕様はこう慎重に述べている。「偶然の一致により、JSONはYAMLのほぼ完全なサブセットだった。」JSONはYAML 1.0(2004年)とYAML 1.1(2005年)の間に登場し、YAML著者たちは重複を後から発見した。1.2改訂の明示的な目標は、著者ら自身の言葉を借りれば「YAMLをJSONの厳密なスーパーセットにすること」だった。これはJSON形式のYAML 1.2文書ではほぼ真だが、YAML 1.1では真ではない。
実際的な意味では、すべてのJSONドキュメントは有効なYAML 1.2であり、フロースタイルのマッピング{"a": 1, "b": [true, null]}はどちらでも同一にパースされる。ほとんどのJSONドキュメントは、真偽値とノルウェー問題のため、YAML 1.1では有効ではない。デフォルト設定の1.1パーサーでラウンドトリップすると、文字列リテラル"NO"を含むJSONドキュメントはfalseとして再出力される。逆は決して成立しない。YAMLはJSONで表現できないものを表現できる。コメント(変換時に失われる)、アンカーとエイリアス(変換時に解決される)、タグ(通常は破棄される)、マルチドキュメントストリーム(最初のドキュメントのみか配列として全体が残る)、マッピングの非文字列キーなどだ。
ノルウェー問題
YAMLで最もよく引用されるゴッチャだ。ISO 3166-1でノルウェーの2文字国コードがNOであり、YAML 1.1の真偽値正規表現がNOをbooleanのfalseとして一致させるため、ノルウェーの名が付いている。YAML 1.1(または1.1動作をデフォルトとしている1.2パーサー、つまりほとんどのパーサー)でcountry: NOと書いてパースし、JSONとして出力すると{"country": false}になる。このバグはサイレントで、警告もなく型エラーもなく、ただデータが壊れるだけだ。
公式yaml.org/type/bool.htmlスキーマにあるYAML 1.1の真偽値正規表現の全文:
y|Y|yes|Yes|YES|n|N|no|No|NO|true|True|TRUE|false|False|FALSE|on|On|ON|off|Off|OFF
6種類の語彙(y/n、yes/no、on/off、true/false)がそれぞれ3つの大文字小文字バリアントを持ち、合計22種類の文字列が警告なしに真偽値へ変換される。有効な値のリスト[y, n, maybe]は[true, false, "maybe"]になり、フィーチャーフラグdark_mode: onはdark_mode: trueとしてパースされ、OFFと書いたポートモード設定はfalseになる。YAML 1.2は仕様レベルでこれを修正した:JSONに合わせたコアスキーマはtrue、True、TRUE、false、False、FALSEのみを認識し、y/n/yes/no/on/offは一切認識しない。しかしこの修正は現場に普及しておらず、PyYAMLとLibYAMLは現在出荷中の全バージョンで依然として1.1がデフォルトだ。このコンバーターはjs-yaml v4を使用しており、YAML 1.2 / JSON互換スキーマがデフォルトとなっている。PyYAMLでyaml.load()を実行して変換するより、ブラウザ側のコンバーターが実際に安全な理由の一つだ。
その他の暗黙型付けの地雷
8進数。YAML 1.1はCの慣例に従い、先頭のゼロは8進数を意味した。そのため010は整数8としてパースされ、permissions: 0777(Unixファイルモードとして自然な書き方)は511としてパースされた。YAML 1.2での修正は、現代のPythonに合わせた明示的な0oプレフィックスを必要とすること。0o777は511であり、0777は単なる777だ。1.1のデフォルトに固定されたままのパーサーはまだこれを誤って処理する。
60進数。YAML 1.1は初期のシリアライゼーション形式からの慣例を受け継ぎ、コロンで区切られた10進数グループの列は基数60(60進数)の整数または浮動小数点数としてパースされた。想定ユースケースは時間の長さで、1:11:00は整数4260(1時間11分を秒で表したもの)としてパースされた。21:00のようなタイムスタンプや2:3:4のようなバージョン番号を書いて整数に暗黙変換されることに今も多くの人が悩まされている。60進数はYAML 1.2でひっそり削除されたが、PyYAMLや他の1.1デフォルトのパーサーはまだ適用している。
日時の自動型変換。YAML 1.1はISO 8601タイムスタンプも自動検出し、ホスト言語のネイティブな日時型としてパースする。文字列が欲しかった場合に問題となる。version: 2024-01-15と書くと、Pythonのdateオブジェクトが得られ、文字列"2024-01-15"にはならない。Ruud van Asseldonkの「地獄のYAMLドキュメント」エッセイが繰り返し説く一般的な教訓:他の何かとしてパースされる可能性がある文字列は常にクォートせよ。国コード・バージョン番号・ファイルモード・タイムスタンプ・固定語彙から選んだ値はシングルクォートまたはダブルクォートで囲むべきだ。
アンカー・エイリアス・マージキー
YAMLのアンカー・エイリアスシステムでは、&nameでノードにラベルを付け、後で*nameで再利用できる。典型的な例:
defaults: &defaults timeout: 30 retries: 3 production: <<: *defaults host: prod.example.com
ここで&defaultsがマッピングにアンカーを付け、<<: *defaults(ほとんどのパーサーが保持している1.1スキーマの機能であるマージキー)がそれをproductionブロックにスプライスする。JSONに変換されると、エイリアスは完全に解決される。JSON出力には参照ではなくリテラルな繰り返しコンテンツが含まれる。アンカーとエイリアスは消え、マージキーはフラット化される。
このシステムの有名な障害モードはビリオンラフス攻撃だ。アンカーは複数回エイリアスでき、エイリアス対象自体にもエイリアスを含められるため、小さなYAMLファイルが巨大なメモリ上の構造に展開される(10段のネスト × 10倍の入れ子 = 10¹⁰個の文字列要素)。PyYAML・LibYAMLなどはこれを軽減するために展開制限を追加しなければならなかった。ブラウザ側のコンバーターは自然なメモリ上限がある(ホストが影響を受けるよりずっと早くタブがOOMになる)が、構造的なリスクは現実のものだ。
マルチドキュメントストリームとフロントマター
YAMLストリームには複数のドキュメントを含められる。ドキュメントはちょうど---のみを含む行で区切られる(最初のドキュメント冒頭のディレクティブ終端マーカーとしても使われるため、Jekyll・Hugo・Eleventyのフロントマターがこの---行で囲まれる)。...のみの行はドキュメントの末尾を示すが新しいドキュメントは開始しない。ストリーミングプロトコルで有用だ。
Kubernetesは---を使って複数のリソースマニフェストを1ファイルにまとめる。JSONには同等の機能がない。コンバーターがマルチドキュメントYAMLを処理する際の選択肢は3つある。最初のドキュメントのみを出力するか、JSONドキュメントの配列を出力するか、---区切りでJSONドキュメントを1つずつ改行区切りで出力する(JSON Lines)かだ。ほとんどのコンバーターは1番目または2番目を選択する。js-yamlのloadAllは配列を返す。
複数行文字列:folded対literal
YAMLにはブロックスカラーのスタイルが2つある。リテラルスタイル(|)は改行をそのまま保持する。折り畳みスタイル(>)は単一の改行をスペースに置き換え、空行を段落区切りとして保持する。どちらもchomping インジケーターを受け付ける。|-と>-はすべての末尾改行を削除し、|+と>+はすべて保持し、修飾子なしの|または>(「clip」)は末尾改行を1つ保持する。JSONに変換されると、どちらのスタイルも通常の文字列値を生成する。折り畳みブロックは保持された空行のみに\nが埋め込まれた1つの長い文字列になり、リテラルブロックはすべての改行に\nがある。
変換で失われるもの
- null表現の統合。YAMLは
null、Null、NULL、~、および空の値(何も続かないkey:)をnullとして受け付ける。5つすべてがJSONnullに変換され、区別できなくなる。 - コメントはサイレントに消える。YAMLのコメントは
#で始まり、1.2仕様はそれが表示専用であり、データモデルの一部ではないと明記している。JSONにはコメント構文がない。保持が必要な場合は、変換前にデータとして(例:_commentフィールド)保存すること。 - 非文字列キーは強制変換される。YAMLのマッピングでは、整数(
1: foo)・真偽値(true: yes)・入れ子のシーケンスを含む任意のノードをキーにできる。JSONは文字列キーのみを要求する。ほとんどのコンバーターは文字列化("1": "foo")し、一部はエラーをスローする。 - タグは通常破棄される。
!!set・!!omap・アプリケーション固有の!myapp/TypeなどのカスタムタグにはJSON上の対応がない。 - 日時は文字列としてラウンドトリップする。JSONはネイティブな日付型を持たないため、YAMLの日付やタイムスタンプは通常JSONではISO 8601文字列になる。
- 大きな整数はJavaScriptで精度を失う。JSのJSON数値はIEEE 754倍精度浮動小数点数のため、
9007199254740993のようなYAMLの整数は変換後に9007199254740992にサイレント変換される。 - アンカーは展開される。複数の位置でサブツリーを共有するYAMLグラフは、そのサブツリーが複製されたJSONツリーになる。サイクル参照(YAMLでは許可)はJSONでは全く表現できない。
YAMLの実際の用途
YAMLは現代のインフラ全体に浸透している。Kubernetesマニフェスト(オブジェクトモデル全体が慣例的にYAML。---で区切るマルチドキュメントファイルが標準)、Docker Compose(サービス・ネットワーク・ボリューム用のdocker-compose.yml)、GitHub Actions(.github/workflows/*.yml:ほぼYAML 1.2の厳格なスキーマが守られているが、パーサーはまだon:をキーとして認識しており、GitHubが明示的に対処しているノルウェー問題すれすれの状況だ)、GitLab CI/CD、Ansibleプレイブック、CircleCI / Travis CI / Drone / Bitbucket Pipelines、Jekyll / Hugo / Eleventy / Gatsby / Astroのフロントマター、OpenAPI / Swagger仕様(公式には「JSONまたはYAMLのいずれかで表現できるJSONオブジェクト」)、Prometheus / Grafana / Loki / Tempo監視スタックの設定、cloud-init(EC2/GCE/Azure VMの初回起動プロビジョニング)、AWS CloudFormation / Azure Resource Manager / Google Cloud Deployment Manager。これらのほとんどで、JSON専用プロトコルへの設定の埋め込み・jqを使ったファイルの比較・JSONを期待するツールへの出力供給など、YAML-to-JSON変換が不可欠だ。
ブラウザ側の変換がサーバー側より安全な理由
PyYAMLのyaml.load()はデフォルト設定で、!!python/objectタグを介して信頼できない入力から任意のPythonコードを実行できた。副作用を持つ実際のPythonオブジェクトにデシリアライズされるもので、CVE-2017-18342(CVSS v3.1スコア9.8、Critical)として記録されている。PyYAML 5.1(2019年3月)で安全でないデフォルトを非推奨にし、safe_load()を推奨エントリーポイントにすることで修正された。JavaのSnakeYAMLにも同様の問題があり(CVE-2022-1471、こちらもCVSS 9.8)、Constructorクラスを介した任意のインスタンス化が可能だった。Rustの事実上の標準クレートであるserde_yamlは2024年3月に非推奨となり、エコシステムは後継(serde_yml・serde_yaml_ng・serde_norway)の選定を進めている。
ブラウザでjs-yaml v4を使ってパースを実行することで、これらすべてを回避できる。侵害するサーバーが存在せず、js-yamlにはタグを介した任意コード実行の概念がなく(未知のタグはオブジェクトとして構築されるのではなくプレーンなスカラーになる)、v4はより安全な1.2スキーマがデフォルトだ。Absolutoolのツールはデフォルトでこのメリットを享受している。
さらなる質問
コンバーターはマルチドキュメントYAMLファイルをどう処理しますか?
js-yamlのloadAllで読み込み、解析済みドキュメントの配列を返す。JSON出力は---区切りドキュメントごとに1要素を持つJSON配列となる。単一のドキュメントの場合は1要素のJSON配列になる。明示的な単一ドキュメントのセマンティクスが欲しい場合は、入力を---/...マーカーで囲むこと。
KubernetesマニフェストはYAML変換で正しく変換されますか?
ほぼ常にyes。KubernetesはYAML 1.2互換のコンテンツを大部分で使用しており、js-yaml v4は標準的なプリミティブ(文字列・整数・真偽値・null・シーケンス・マッピング)に加えアンカーとエイリアスをすべて処理する。変換で残らない2つは、コメント(削除される)と参照ではなく繰り返しコンテンツに展開されるアンカーだ。
なぜ国コードNOが真偽値として読み込まれるのですか?
このコンバーターでは起きないはずだ。js-yaml v4はYAML 1.2 / JSON互換スキーマがデフォルトで、y/n/yes/no/on/offを真偽値として認識しない。別のツール(PyYAMLなど)でこの問題が起きている場合は、値をクォートで囲むことで解決する:country: "NO"。
ファイルサイズの上限は?
アップロードウィジェットでは5MBだが、ブラウザのメモリが十分あればペーストしたコンテンツはより大きくても構わない。ボトルネックはネットワークではなくメモリ上の表現であり、サーバーは介在しない。50MB超のファイルには、代わりにデスクトップYAMLツールチェーン(コマンドラインのyqなど)を検討すること。