JSON 差分チェッカー
2つのJSONオブジェクトを比較し差異を可視化。RFC 6902 JSON Patchオペレーションとカラーツリーdiffを出力。ブラウザ内で処理。
- ブラウザ内で処理
- データはブラウザ外に出ません
- 無料 · 登録不要
WeChat でスキャンしてシェア
例・詳しい説明・よくある質問 実際の出力つきの例、ほかのツールとの違い、よくある質問。
ユースケース
- バージョン間のAPIレスポンスの変化を確認する。
- PATCH HTTPエンドポイント用のパッチ操作を生成する。
- 設定ファイルの変更を監査する。
- アプリケーション内の予期しないデータ変異をデバッグする。
関連ツール:JSON 整形・構文チェック — diff前にJSONを整形・検証する。
例
変更前:
{"name":"Alice","status":"pending","legacy_id":12345,"tags":["a","b","c"],"profile":{"age":30,"city":"Paris"}}
変更後(キーの順序が変わり、status を変更、legacy_id を削除、role を追加、最初のタグを削除):
{"status":"active","name":"Alice","role":"admin","tags":["b","c"],"profile":{"age":31,"city":"Paris"}}
ビジュアル差分:
~status: "pending" → "active"
−legacy_id: 12345
~tags.0: "a" → "b"
~tags.1: "b" → "c"
−tags.2: "c"
~profile.age: 30 → 31
+role: "admin"
JSON Patch:
[
{ "op": "replace", "path": "/status", "value": "active" },
{ "op": "remove", "path": "/legacy_id" },
{ "op": "replace", "path": "/tags/0", "value": "b" },
{ "op": "replace", "path": "/tags/1", "value": "c" },
{ "op": "remove", "path": "/tags/2" },
{ "op": "replace", "path": "/profile/age", "value": 31 },
{ "op": "add", "path": "/role", "value": "admin" }
]
キーの順序は結果に影響しません。name は位置が変わっても報告されません。この patch を Python の jsonpatch 1.33 で適用すると 変更後のドキュメントになります:
import jsonpatch # pip install jsonpatch
before = {"name": "Alice", "status": "pending", "legacy_id": 12345,
"tags": ["a", "b", "c"], "profile": {"age": 30, "city": "Paris"}}
patch = jsonpatch.JsonPatch([...]) # paste the patch from the tool
after = patch.apply(before)
配列の比較方法
配列は内容ではなくインデックスで比較されます。["a","b","c"] から最初のタグを外すと、remove /tags/0 1件ではなく、置換2件と削除1件として表示されます。patch は正しいものの、必要以上に長くなります。
同じ配列から複数の要素を削除するときは、大きい添字から順に書き出します。例として、3 行あった注文明細が 1 行になり、数量も変わった場合:
[
{ "op": "replace", "path": "/items/0/qty", "value": 3 },
{ "op": "remove", "path": "/items/2" },
{ "op": "remove", "path": "/items/1" }
]
remove /items/2 の後も配列には 2 要素あるので、/items/1 はまだ存在します。小さい添字から書くと 2 つ目の削除が配列の末尾を越え、1 つでも操作が失敗するとパッチ全体が失敗します(RFC 6902 第 5 節)。短い方の配列を超える要素は remove(大きい添字から)か add(小さい添字から)になります。
パスと JSON Pointer のエスケープ
patch のパスは JSON Pointer(RFC 6901)で、~ は ~0、/ は ~1 と書きます。{"a/b":1,"m~n":2,"list":[1,2,3]} → {"a/b":2,"list":[1,2,3,4],"x":null} の結果:
[
{ "op": "replace", "path": "/a~1b", "value": 2 },
{ "op": "remove", "path": "/m~0n" },
{ "op": "add", "path": "/list/3", "value": 4 },
{ "op": "add", "path": "/x", "value": null }
]
ルートの型が異なる場合(オブジェクトと配列など)、パッチはドキュメント全体を置き換え、パスは空文字列 "" になります(RFC 6901 では / は名前が空文字列のメンバーを指します):
[
{ "op": "replace", "path": "", "value": [1] }
]
ビジュアル差分はキーをドットでつないで表示します(profile.age、list.3)。読みやすさのための表記なので、コードでは JSON Patch のパスを使ってください。
制限
- move と copy の操作は生成しません。キー名の変更は
removeとaddとして表示されます。 - オブジェクトの配列を
idフィールドで対応付けることはしません。 - 両方とも有効な JSON である必要があります。ステータス行にどちらの解析に失敗したかが表示されます(例:
変更前 JSON の解析エラー:Expected double-quoted property name in JSON at position 7)。 - 数値は JavaScript で解析してから比べるため、
1.0と1は同じとみなし、2^53 を超える整数は精度が落ちます。 - ツールのテストでは、生成したパッチを厳密な RFC 6902 実装(インストールされていれば Python の
jsonpatchも)で「変更前」に適用し、結果が「変更後」と一致することを確かめています。ランダムな 3,000 組の文書でも確認しています。
FAQ
RFC 6902 JSON Patchとは何ですか?
RFC 6902はJSONドキュメントに適用する操作列を表現するJSON文書形式を定義しています。各操作は'op'(add/remove/replace/move/copy/test)・'path'(RFC 6901 JSON Pointer)・オプションの'value'を持つオブジェクトです。
JSONデータはサーバーに送信されますか?
いいえ。比較はすべてブラウザ内のJavaScriptで行われます。データは一切外部に送信されません。
大きなJSONファイルを比較できますか?
可能ですが、数千のキーや深くネストした配列を含む非常に大きなオブジェクトは処理に少し時間がかかる場合があります。すべての計算はブラウザ内で完結します。
ビジュアルdiffはどのように機能しますか?
深い再帰比較を行います。「After」にのみ存在するキーは追加(+)として表示。「Before」にのみ存在するキーは削除(−)として表示。値が変化したキーは変更(~)として旧値と新値を並べて表示します。
テキスト差分チェッカーとの違いは?
テキスト差分チェッカーは平文を行単位で比較します。このJSONdiffツールはJSON構造を理解し、テキストではなく意味的に値を比較し、機械可読なJSON Patch操作を出力します。