メインコンテンツへ移動

TOMLからJSONへ

アップロードは一切不要です。このコンバータはブラウザ内でTOML 1.0を解析し、JSONを出力します。テーブルはオブジェクトになり、[[配列のテーブル]]のエントリーはオブジェクトの配列になり、RFC 3339の日時は文字列のまま保持されます。重複するキーは、黙ってマージされる代わりに行番号付きのエラーで失敗します。JSONはRFC 8259に準拠します。

端末内で処理

TOMLからJSONへとは

TOMLは特定のニッチを占めています:Cargo.toml、pyproject.toml、そして数多くのパッケージマネージャーが採用する設定形式で、人間が編集しても壊さないことが選ばれる理由です。JSONは別の領域を占めています――プログラムが交換する形式です。いずれにせよ、スクリプト、テストフィクスチャ、またはAPIがTOMLをJSONとして必要とする時が来ます。その変換には、まさに2つの技術的な疑問があります:[テーブル]ヘッダーがJSONオブジェクトになるにはどうすればよいのか、そして[[配列のテーブル]]ヘッダーがJSON配列になるにはどうすればよいのか?

マッピングは決定論的です。[テーブル]とそのキーはネストされたオブジェクトになり、database.portのようなドット付きキーもネストされたオブジェクトになります。[[配列のテーブル]]は、ヘッダーごとに1つのオブジェクトを持つ配列になります。TOMLのスカラーは直接マップされます――ブール値はブール値のまま、整数と浮動小数点数は数値のままです。読みやすさのためにTOMLが許すアンダースコアは消えます。なぜなら1_000_000と1000000は同じ数値だからです。RFC 3339の日時にはJSONの型がないため、テキストが正確に保持された文字列として出力されます。

すべてはこのブラウザのタブ内で動作します。貼り付けたTOMLテキストはページ内エンジンによって解析され、JSONは解析されたドキュメントからシリアライズされます。どちらもネットワークを介することはありません。DevToolsを開き、変換中にネットワークパネルが静まっているのを確認してください。ページのContent-Security-Policyは送信接続を禁止しているため、プライバシーの主張は装飾ではなく検証可能です。

往復変換は一般的なワークフローです――ペイロードから設定を取り出し、編集し、戻す――そしてそのJSONをTOMLに変換し直すページはこのマッピングを逆方向で実行し、まずスカラーから処理します。

このツールが出力するJSONはデフォルトでコンパクトなので、読みやすくするためにインデントしたい場合、JSONフォーマッターが選択したスペースで再出力します。

変換の実際の仕組み

エンジンはまずTOMLをドキュメントツリーに解析します。なぜなら、すべてのJSONの決定はTOML自身のスコーピングルールに従うからです。[テーブル]ヘッダーは名前付きオブジェクトを開き、[[配列のテーブル]]ヘッダーは名前付き配列に新しいオブジェクトを追加し、ヘッダーの上にあるキーはルートオブジェクトに属します。ツリーが存在すれば、JSONを出力することは単純なシリアライズです。唯一の判断はTOMLとJSONが一致しない場所で、それぞれの場所は毎回同じように決定されます:

  • テーブル:[owner]にnameキーがあると、ownerオブジェクトが生成されます――TOMLのヘッダーとJSONの波括弧は同じネストをエンコードします。
  • テーブルの配列:各[[servers]]ヘッダーは、ファイルの順序に従ってservers配列に1つのオブジェクトを追加します。
  • ドット付きキー:database.port = 5432は、TOML 1.0が定義するドット付きキーの動作と全く同じように、databaseの下にネストします。
  • 日時:1979-05-27T07:32:00ZにはJSONの型がないため、文字列"1979-05-27T07:32:00Z"として、バイト単位で正確に出力されます。
  • 数値:アンダースコアはTOMLの句読点であり、データではありません――1_000_000は1000000として出力されます――TOMLのinfとnanはnullになります。なぜならJSONにはそれらのリテラルがないからです。

出力の見た目

以下の作業例は、コンバーターの「サンプルを読み込む」ボタンが生成する正確なペアです:3つのスカラーキー(そのうち1つはアンダースコア付き)、[issuer]テーブル、2つの[[items]]エントリー。各形状の変換に注目してください――アンダースコアは数値内で消え、issuerテーブルはオブジェクトとしてネストし、items配列はファイルの順序でオブジェクトを収集します。キーはTOMLで宣言された順序のままです。なぜなら、文書の順序はコンバーターが誠実に保てる唯一の順序だからです。

JSONが解析されたツリーからテキストのスプライシングではなく出力されるため、フォーマットも正規化されます。TOML内の2つのスペーススタイルは1つの一貫したJSONを生成し、余分な空行は何も変更しません。生き残るのは構造と値だけです――まさにコンバーターが約束すべきものです。

重複キーとその他の誠実な失敗

誠実なコンバーターは、忠実に表現できない入力を拒否します。TOML 1.0は十分に厳密で、拒否は稀で曖昧ではありません。3つの入力は、黙って再形成される代わりに、特定の行番号付きメッセージで拒否されます:

  • 重複キー――TOML 1.0はキーを複数回定義することを禁止しているため、パーサーは問題のある行で停止し、最後のものが勝つという形で静かに設定を書き換えることを許可しません。
  • 複数行文字列――このパーサーがサポートするサブセットは、単一行の基本文字列とリテラル文字列をカバーしています。"""ブロックは、不正確な推測ではなく、正確にそれを示すメッセージ付きで拒否されます。
  • 閉じていない構造体――終わらない[テーブル]ヘッダーまたは引用符は、パーサーが断念した行を報告し、一般的な構文エラーではありません。

マッピングの概要

このコンバーターがサポートするすべての構造体と、それらがJSON内でどこに配置されるか:

TOML 1.0JSON出力
[owner]テーブルネストされた"owner"オブジェクト
[[items]]ヘッダー"items"オブジェクトの配列
database.portドット付きキーネストされた"database"オブジェクト
1979-05-27T07:32:00Z文字列、RFC 3339のテキストが保持される
1_000_000数値1000000
'リテラル文字列'文字列、バックスラッシュはそのまま

よくある質問

TOMLをJSONに変換する際、ファイルはどこかにアップロードされますか?

いいえ。解析とシリアライズの両方が、ページが開いた時に読み込まれたJavaScriptを使ってこのブラウザのタブ内で実行されます。データを送信するAPIルートはなく、Content-Security-Policyが送信接続をブロックします。両方の主張を数秒で確認できます:DevToolsを開き、変換中にネットワークパネルを確認し、リクエストが送信されていないことを見てください。

JSON出力ではTOMLの日時はどうなりますか?

文字列になります。JSON(RFC 8259)には日付や日時の型がありません――文字列、数値、ブール値、null、オブジェクト、配列のみです。そのため、1979-05-27T07:32:00Zは正確な文字列"1979-05-27T07:32:00Z"として出力されます。再フォーマットやタイムゾーンのシフトは何も行われません。テキストはバイト単位で生き残り、下流のコードが必要に応じて実際の日付を解析します。

[[配列のテーブル]]は[テーブル]とどう違いますか?

二重括弧は追加、単一括弧は定義です。[servers]は1つの名前付きオブジェクトを作成します。2番目の[servers]ヘッダーは重複キーエラーになります。[[servers]]は配列を作成し、ヘッダーごとに1つのオブジェクトを追加するため、3つの[[servers]]ブロックは3要素の配列になります。単一と二重の区別が唯一の違いであり、それがこのコンバーターが逆方向でもそれを保持する理由です。

なぜ重複キーはエラーになり、上書きされないのですか?

なぜならTOML 1.0はキーを複数回定義することを無効であると宣言しており、衝突を解決するコンバーターは、その仕様が拒否するファイルを認証することになるからです。エラーは2番目の定義の行番号を示しており、それは通常、あなたが見つけ必要としていたタイプミスや悪いマージです。

私のTOMLは三重引用符の複数行文字列を使っています――なぜエラーになりますか?

このパーサーはTOML 1.0の文書化されたサブセットをサポートしています:単一行の基本文字列、単一行のリテラル文字列、整数、浮動小数点数、ブール値、日時、テーブル、配列のテーブル、ドット付きキーです。複数行文字列はサブセット外であり、部分的に解析される代わりに、明確な名前付きメッセージ付きで拒否されます。値を\nエスケープ付きの単一行文字列に分割すれば、きれいに変換されます。

私のinfとnanの値はどうなりましたか?

TOMLは浮動小数点数のinfとnanを許可しますが、JSONにはそれらのリテラルがありません――JSON.parseはそれらを生成できず、JSON.stringifyはnullを書き込みます。コンバーターはこれら2つの値に対してnullを出力し、プレビューでそれらをフラグします。なぜなら、無限を有限に見える数値に静かに変換することは、追跡に何時間もかかるような嘘だからです。