メインコンテンツへ移動

2つのJSONファイルを比較する方法

2つのJSON文書をJSON差分比較ツールの左右のペインに貼り付け、比較を実行し、生成された変更リストを読みます。追加、削除、値の変更が、キー順と空白を無視して並びます。すべてブラウザ内で動作します。差分の機械可読な記録が必要になったら、結果をRFC 6902パッチとしてエクスポートしてください。

端末内で処理
ツールだけ使いたい方はJSON差分比較へキー順を無視して意味ベースで比較し、RFC 6902パッチを出力ツールを開く

2つのJSONファイルを比較する方法とは

2つのJSON文書が大きく対立することはまれです。片方にだけキーがある、設定のネストが1つ深い、片方は数値を引用符で囲みもう片方は素のまま——行単位のdiffは、こうした見た目の違いひとつひとつに、赤い壁で答えます。本当に知りたいのは、もっと小さくて有用なことです。どの値が変わったのか。どのキーが現れ、消えたのか。そして、依存している構造が期待どおりの形を保っているのか。

このページでは、サイトのJSON差分比較ツールを使ってこの作業を端から端まで案内します。4つのステップ、各ステップに、次へ進む前に実行できるチェックが付いています。比較の全体がブラウザ内で動きます。文書はローカルで構文木にパースされ、タブの外に出ません。だからこそ同じ手順が、ホスト名を含む設定ファイルにも、すでにローテーション済みの資格情報にも、見知らぬ人のフォームフィールドに貼りたくない顧客データにも、安全に使えます。

始める前に、このツールが何を教えてくれて、何を教えてくれないのかを知っておいてください。ツールは渡された2つの文書を比較します。git履歴も、デプロイも、意図も知りません。変更リストは2つの文書についての事実であって、誰が何をなぜ変えたのかの説明ではありません。物語の後半が必要になったときにどこを見ればよいかは、以下のステップの中に含めています。

以下のステップはすべてJSON差分比較ツールのなかで行われます——2つのペイン、1回の比較操作、そして見た目の違いを一切無視する変更リスト。

オブジェクト、配列、キーという語彙に馴染みがなければ、JSONとは何かのガイドが、比較を始める前に平易な言葉で解説してくれます。

手順

  1. ツールを開き、1つ目の文書を読み込む

    「JSON差分比較」を開き、1つ目の文書を左ペインに入れます。貼り付けても、ファイルをペインにドラッグしてもよく、まずサンプルデータで練習したいなら組み込みの例を読み込んでも構いません。ファイルを読むのはブラウザ自身です。この手順に、アップロードのステップは一切ありません。

    確認:左ペインがパースエラーなしで文書を受け入れたなら、JSONは比較できる程度には正しいということです。そこでパースエラーが出たら、ほかの何かが動く前に、どの行を直すべきかをツールが教えてくれているのだと読みます。

  2. 2つ目の文書を右側に読み込む

    2つ目の文書も、同じ方法で右ペインに入れます。順序が意味を持つのは名付けの話であって、正しさの話ではありません。左が基準であり、右がそれと比較される側です。向きを間違えたときは、「入れ替え」ボタンが場所を取り替えます。両側が読み込まれたら、比較を実行できます。

    確認:両方のペインに、エラーではなく文書が入っています。片方しかパースできないなら、比較は始められません。文書と無を比較する前に、失敗している側を直してください。

  3. 比較を実行し、変更リストを読む

    比較を実行します。結果は、本当の差分のリストです。片方に追加されたキー、もう片方から削除されたキー、そして変わらないキーパスの下で変わった値。キー順と空白は意図的に無視されます。{"a":1,"b":2}と{"b":2,"a":1}はここでは同じ文書であり、そう言い切ることが意味的な比較の要点です。Alt+↑とAlt+↓を使えば、マウスに手を伸ばさずにリストをたどれます。

    確認:存在を知っている変更が(練習したければ、比較の前に値を意図的に変えておいてください)、まわりの行すべての書き換えではなく、ちょうど1行として現れます。それが、テキストではなく意味を読んでいるという合図です。

  4. 差分をパッチとしてエクスポートする

    リストの内容が正しいことを確認したら、RFC 6902のJSON Patchとしてエクスポートします。各変更に対してadd、remove、replaceを告げる、小さく順序付けられた文書です。このパッチこそが、読むセッションを記録に変えます。同僚に渡し、チケットに添え、あるいは別の場所で左の文書に適用して、右側を正確に再現してもらいましょう。

    確認:エクスポートされたパッチ自体が有効なJSONで、どちらの文書よりも明らかに小さいはずです。左文書のコピーに適用すれば、右側が再現されるはずです。

意味的な比較があえて無視するもの

ツールは両方の文書を木構造にパースし、その木を比較します。そのため、3種類の違いは変更リストに現れません。キー順。オブジェクトはマッピングであって列ではなく、キーを書いた順序に意味を読み取る利用者はいません。意味のない空白。インデントやスペースは見た目であり、片側を再整形しても変更が1つも出ないべきものです。値が等しい場合の数値の書き方。重要な比較において、1と1.0は同じ数を指します。

リストに現れるのは、文書の意味を変えるものすべてです。変わった値、現れたり消えたりしたキー、型の変化——文字列「42」が数値42になるのは本当の変更であり、ツールはそれを黙って受け入れるのではなく、変更として分類します。期待した変更が見当たらないとき、まず正直に問うべきは、それが見た目の3種のどれかではなかったかです。

配列——位置で合わせるか、キーで合わせるか

配列は、意味的な比較が判断を迫られる唯一の場所です。["a","b"]と["b","a"]は2通りに読めるからです。すべてが移動したのか、何も変わっておらず順序に意味があるのか。ツールはその選択を委ねています。インデックス一致は配列を列として扱い、主キー項目による一致は、データベースのように要素を同一性で並べ合わせます。

レコードのリスト(ユーザー、ホスト、イベント)では、キー一致がほとんどの場合に正解です。先頭に新しいレコードを挿入しても、全行のごたごたではなく、追加が1件出るだけで済みます。順序そのものに意味があるリスト——手順のステップ、ランキング結果——では、インデックス一致が正直な選択です。デフォルトに判断を委ねるのではなく、意図して選んでください。

大きなファイルと、処理が実際に動く場所

比較はWeb Workerで、ページのメインスレッドから離れて動き、文書1件あたり100 MBまでを受け付けます。実際的な帰結として、大きなペアでも比較にはそれなりの秒数がかかります。ただし処理の間もタブは生きており、固まった画面を見つめる代わりに、すでに表示されている変更リストをスクロールし続けられます。

3者間マージモード——ベース文書に2つの変更済みブランチが合流する形——はページ自身の中で計算するため、上限が8 MBになります。マージの入力がそれを超えるなら、前述の2文書比較はフルサイズのまま使えます。

JSONの比較が不向きなとき

形式の異なる2つの文書——JSONの設定ファイルと、そのYAML訳——は、先に片方を変換する必要があります。さもなければ、diffの全行が「入れ物が違う」と言うだけに終わります。片方をもう片方の形式に変換してから比較してください。そして、そもそも構造化されていない問い——2つのログファイル、2段落の文章——には、プレーンテキストの比較こそが正しい道具であり、JSONの仕組みはノイズを足すだけです。

逆もまた然りです。変更リストを読みながら、意図を声に出して語ってしまっている——「ここでタイムアウトを移したんだ」——なら、diffの仕事はすでに終わっており、変更の記録は構造化された場所に属します。RFC 6902のエクスポートが存在するのはまさにそのためです。読み取りのセッションが、記憶ではなく成果物で終わるように。

よくある質問

ここで比較すると、JSONファイルはアップロードされますか?

いいえ。両方の文書はブラウザのタブ内でパースされ、比較されます。比較エンジンは自分のマシン上のWeb Workerで動き、送り先となるアップロード用エンドポイントは存在しません。DevToolsで確認できます。Networkパネルを開いて比較を実行しても、あなたのデータを運ぶリクエストはありません。ページのContent-Security-Policyも、構造上、外向きの接続を拒否します。

キーの並べ替えが差分として表示されないのはなぜですか?

オブジェクトはマッピングであって順序付きリストではないからです。{"a":1,"b":2}と{"b":2,"a":1}はまったく同じ情報を運び、すべてのJSONパーサーが両者から同じ木を作ります。キーの並べ替えを報告するdiffが本当に報告しているのは書式であって、意味的に何が変わったかを知りたい読み手にとってはノイズです。空白が無視されるのも、同じ理由です。

RFC 6902パッチとは何ですか?なぜエクスポートするのですか?

RFC 6902はJSON Patchを定義しています。操作——add、remove、replace、move、copy、test——を列挙し、それぞれが特定のパスを指すJSON文書です。比較結果をこの形式でエクスポートすると、変更リストが機械適用可能な記録になります。同じパッチを左の文書に適用すれば右側が再現されるため、同僚への正確な引き継ぎ、テストフィクスチャ、移行スクリプトとして使えます。

2つのJSONファイルはどれくらい大きくできますか?

文書あたり100 MBまでです。パースと比較はWeb Workerで動くため、大きなペアではそれなりの時間がかかりますが、タブは固まりません。ワーカーの動作中もインターフェースは応答を保ち、すでに描画済みの行はスクロールできます。別機能の3者間マージモードには、それより小さい8 MBという独自の上限があります。あちらの計算はページのメインスレッドで動くためです。

すべての行が変わった扱いにならずに、配列を比較できますか?

はい——それが配列のマッチング設定です。インデックス一致は要素0を要素0と比較するもので、順序に意味がある場合に適しています。キー一致は、選んだ項目(id、slug、ホスト名など)で要素を並べ合わせるもので、レコードのリストに適しています。新しい行を1件挿入したら、リスト全体の書き換えではなく、変更が1件だけ現れるべきだからです。どちらの答えもすべての配列に正しいわけではないため、この設定が存在します。

diffは、どの変更が先に起きたか、誰がしたかを教えてくれますか?

いいえ。どんなdiffにも無理です。比較が見るのは2つの文書であって、時間軸ではありません。値が変わったことはわかりますが、いつ、誰が、なぜなのかはわかりません。その履歴は、バージョン管理、デプロイログ、あるいはファイルを編集した何らかのプロセスの中にあります。パッチのエクスポートがその橋渡しです。物語が語られているチケットやコミットに添えてください。