CSVをJSONに変換
CSVからJSONへの変換は、表計算ソフトのエクスポートを、ブラウザ内でレコードの配列へ解析します。RFC 4180を正しく解釈するため、カンマ、改行、エスケープされた引用符を含む引用付きフィールドは、すべてそのまま保持されます。スカラー型を推定し、ドットや角括弧を含むカラム名から、ネストしたオブジェクトと配列を再構築します。
CSVをJSONに変換はどう動きますか?
この変換の素朴な実装は1行で書けます。line.split(",")です。しかし実際のファイルのかなりの割合では、それは間違っています。CSVのフィールドは引用符で囲まれていることがあり、囲まれたフィールドには区切り文字、そのままの改行、そして1つの引用符を表す2連の引用符が含まれ得ます。カンマで分割すると"Hopper, G."は2つのフィールドに分かれ、それ以降のすべてのカラムが1つずれます。エラーとして止まるのではなく、レコードを壊したまま通してしまうのです。
そこでこのパーサーは、文字ストリーム上を進む明示的なステートマシンであり、RFC 4180の記述どおり、今が引用領域の内側かどうかを追跡します。さらに、RFCには書かれていないものの、実際のファイルには存在する事柄も処理します。最初のカラム名の前に付くUTF-8のバイトオーダーマーク(BOM)、1つのファイルに混在するCRLFと素のLF、そのままでは幻の空レコードを生む末尾の改行、そして引用符なしフィールドの途中に紛れ込んだ迷い引用符。Excelが書き出すこの引用符は、致命的として扱われる代わりに、文字通りに解釈されます。
区切り文字の判定では、ヘッダー行に現れる候補(カンマ、セミコロン、タブ、パイプ)を数えます。ただし数えるのは引用領域の外側だけです。ヘッダーがname,descriptionであり、引用されたdescriptionの中にセミコロンが入っているファイルを、そうしなければ間違った文字で分割することになります。これは、設定間違いではなくデータ破損に見える種類のバグです。
型推定は意図的に控えめです。JSONの数値文法に一致するセルは数値になり、true / falseはブール値になり、nullはnullになります。それ以外はすべて文字列のままです。007もそうです。文法は先頭のゼロを禁じており、部品番号に勝手に番号を付け替えさせるわけにはいかないからです。2 53を超える整数も文字列のままです。変換してしまうと、桁が丸ごと落ちるからです。
最後に、パスに見えるカラム名はパスとして扱われます。customer.nameはネストしたオブジェクトを再構築し、tags[0]は配列を再構築します。これらの名前はファイルから来るため、オブジェクトのインデックスに使われる信頼されていない入力です。a.__proto__.pollutedという名前のカラムはプロトタイプ汚染のペイロードであり、従われる代わりに拒否されます。
CSV入力
id,user.name,tags[0],tags[1] 1,Ada,a,b 2,"Hopper, G.",c,
JSON出力
[
{ "id": 1, "user": { "name": "Ada" }, "tags": ["a", "b"] },
{ "id": 2, "user": { "name": "Hopper, G." }, "tags": ["c"] }
]CSV入力 → JSON出力
CSV入力
id,name,joined 1,Ada,1815-12-10 2,Grace,1906-12-09
JSON出力
[
{
"id": 1,
"name": "Ada",
"joined": "1815-12-10"
},
{
"id": 2,
"name": "Grace",
"joined": "1906-12-09"
}
]CSVをJSONに変換が対応するオプションとエッジケースは?
| パラメータ | 型 | デフォルト | 動作とエッジケース |
|---|---|---|---|
| 区切り文字 | auto | , ; tab | | 自動 | 自動検出はヘッダ行で候補を数え、引用符内の内容は無視します。ファイルのヘッダが本体を正しく反映していない場合は、この設定を上書きしてください。 |
| ヘッダー行 | 真偽値 | true | 1行目がキーを提供します。この設定がオフの場合、キーはcolumn1、column2といったように連番になります。空のヘッダセルは位置名にフォールバックするため、レコードがキーを欠けることはありません。 |
| 型の推定 | 真偽値 | true | JSONの数値構文とtrue/false/nullを適用します。"007"、"+1"、"0x10"、"1,5"は文字列のままです。すべての列をテキストとして保持する必要がある場合(例:数字で構成されたID列)は、この設定をオフにしてください。 |
| パスの展開 | 真偽値 | true | customer.nameやtags[0]から階層構造を再構築します。この設定がオフの場合、キーが実際の列名であるフラットなオブジェクトが生成されます。これは列名が本当に"user.name"である場合に望ましい動作です。 |
| 空セル | 省略 | 保持 | 省略 | CSVは存在しないフィールドと空文字列を区別できません。列の集合がユニオンであるため、省略がより良いデフォルトです。tags[1]が単に存在しないレコードは、tags[1]が""であるレコードとまったく同じように空セルとして書き込まれます。 |
| 引用符付きフィールド | RFC 4180 | — | 引用符で囲まれたフィールドには、区切り文字、CR、LF、および二重引用符を含めることができます。引用符が閉じていない場合は、行番号と列番号が示されるハードエラーとなります。なぜなら、静かに切り捨てると、一見正しいが実際は間違った出力が生成されるためです。 |
| 列数が不揃いの行 | 警告 | — | フィールドの数が正しくない行は、削除されず保持されます。不足しているフィールドは省略され、余分なフィールドは無視されます。影響を受けた行数が警告として表示されます。 |
| 重複列 | 警告 | 最も右を優先 | 表計算ソフトのインポート動作と一致します。ユーザーがファイルで確認できる列を黙って破棄するより、明示的に警告を表示する方が良いので、警告が表示されます。 |
よくある質問
フィールドにカンマが含まれていると、ファイルが正しく変換されないのはなぜですか?
起きないはずです。このパーサーは引用を正しく追跡するので、"Hopper, G."は1つのフィールドのままです。2つに分割されるなら、その変換器は引用符を考慮せずにカンマで分割しています。これはCSVで最もよくあるバグです。ここで起きた場合は、ソースファイルでそのフィールドが本当に引用符で囲まれているか確認してください。引用符なしのカンマは本質的に曖昧で、復元できるパーサーは存在しません。
IDカラムの先頭のゼロが消え続けるのはなぜですか?
ここでは消えません。"007"は文字列のままです。JSONの数値文法は先頭のゼロを禁じており、そのルールこそが部品番号、郵便番号、アカウント参照を守っているからです。ゼロが消えるなら、エクスポート前の表計算ソフトの段階で起きています。Excelは、カラムがTextに設定されていないと、インポート時にゼロを剥ぎ取ります。すべてのカラムをテキストとして保持したい場合は、Infer typesをオフにしてください。
ヘッダーにcustomer.nameとあると何が起きますか?
ネストしたオブジェクトを再構築します。{"customer":{"name":"…"}}の形です。tags[0]のような角括弧付きの名前は配列を再構築します。これは「JSONをCSVに変換」が書き出すものの逆であり、ドキュメントは表計算ソフトを経由する往復に耐えます。カラム名に本当にドットが含まれていて、そのまま扱いたい場合は、Expand pathsをオフにしてください。
フィールドの中に改行を含むファイルも扱えますか?
扱えます。ただしフィールドが引用符で囲まれていることが条件で、RFC 4180もそれを要求しています。複数行にわたる住所やコメントはエクスポートでよくあるもので、正しく処理されます。扱えないのは、レコード途中の引用符なしの改行です。行の終わりと区別する手がかりが何もないからです。
どのくらいの大きさのファイルまで変換できますか?
8 MBまでです。変換はメインスレッドで動くため、この上限を超えると、試みる代わりにメッセージとともに拒否されます。試みたところでタブが固まるからです。どのサイズでもアップロードは一切ありません。ファイルはブラウザが読み取り、どこへも送信されません。
表計算ソフトのデータはサーバーに送られますか?
いいえ。解析は、すでに開いているページの中で行われます。このツールでは特に重要な点です。CSVのエクスポートは通常、本物のレコード(顧客、注文、給与)だからです。再フォーマットのために未知のエンドポイントへ送ることは、取り消せない情報開示です。Networkパネルを開いて、貼り付けている間の様子を眺めてみてください。