JSON Diff 是一個瀏覽器型工具,能以解析後的資料結構(而非原始文字)來比較兩份嚴格的 JSON 文件,並在 RFC 6901 JSON Pointer 路徑上產生一個確定性的新增、刪除、變更與型別變更項目清單。不同於以行為基礎的文字差異比較,它會忽略空白、縮排與物件成員順序,因此真正的值、型別、鍵以及陣列位置變更仍然清楚可見,不會被排版雜訊淹沒。輸出是一份精簡、可直接複製的變更清單,在每個受影響的路徑上附上變更前後的值,適用於程式碼審查、工單留言或手動對帳。由於兩端都依據 RFC 8259 進行解析,因此註解、尾端逗號、未定義值、NaN、Infinity、BigInt 字面值以及 JavaScript 物件語法會在比較開始前就被拒絕。每個輸入可以是任何 JSON 值——物件、陣列、字串、數字、布林值或 null——而且比較是在瀏覽器中於本機執行,因此文件絕不會離開你的電腦。正是嚴格解析、結構化比較與本機處理三者的結合,讓這個工具成為找出兩份 JSON 檔案差異的可靠方式。

difference between json and json
difference between json and json

JSON Diff 實際上比較的是什麼

JSON Diff 接收兩份嚴格的 JSON 文件,將其解析為原生資料結構,然後並列走訪兩棵樹。在每個位置,它會將左側值與右側值之間的關係歸類為四種之一:新增、刪除、變更或型別變更。位置本身會以 RFC 6901 JSON Pointer 記錄,這是與 JSON Patch 及許多 API 契約相同的路徑語法,因此對於已熟悉 JSON 協定的使用者來說,閱讀結果相當自然。

物件是依據自身的成員名稱(而非原始文字順序)進行比較,鍵在回報前會先排序,使輸出在不同次執行間保持穩定。陣列則使用以零為基底的索引按位置進行比較,這表示重新排序會產生一個真實、可見的變更,而非被當作靜默的重新命名。基本型別會同時檢查型別與值:一個數字變成字串屬於型別變更項目,兩個內容不完全相同的字串屬於變更項目,而正零與負零會被視為相同的數值。

每一個差異都會連同產生該差異的值一併回報。新增項目包含右側的值,刪除項目包含左側的值,變更項目則兩者都包含。當整個子樹移動、變更型別或消失時,完整的巢狀物件或陣列會以值的形式完整呈現,而非被摘要略過,因此審閱者可以清楚看到實際影響範圍。

為什麼結構化差異比較勝過文字差異比較

以行為基礎的文字差異比較把 JSON 當作自由形式的散文來處理。只要把某個物件從兩個空格的縮排改成四個空格、按字母順序重新排列成員,或透過美化工具重新儲存檔案,文字差異比較就會點亮一大堆虛假的變更。審閱者得浪費時間去判斷真正的編輯究竟埋在排版雜訊中,還是整個差異完全是表面上的。

JSON Diff 透過先解析兩份輸入跳過了上述所有問題。解析完成後,空白變得不相關,物件成員順序也不再是一個屬性,因此變更清單中出現的項目只會對應到鍵、值、型別或陣列位置上的真實差異。實際效果是審閱範圍大幅縮短,也更加值得信賴。

面向文字差異比較JSON Diff
輸入被視為原始字元已解析的 JSON 結構
空白與縮排視為差異忽略
物件鍵順序視為差異忽略
陣列比較方式依行位置依以零為基底的索引
輸出格式行內的新增與刪除在 JSON Pointer 路徑上的結構化變更清單
偵測型別變更是,作為獨立類別
回報精確位置依行與欄依 RFC 6901 JSON Pointer

比較是在瀏覽器中於本機執行,因此文件絕不會離開你的電腦。沒有上傳、沒有伺服器往返,也沒有任何第三方處理程序存取你的資料。對於設定檔、API 回應,或任何可能包含密鑰或個人資訊的 JSON 而言,這種本機處理模式除了是一項技術細節之外,更是一項實務上的保護措施。

如何比較兩份 JSON 文件

當你手邊有兩份 JSON 文件並需要一份乾淨、確定性的實際差異清單時,請使用 JSON Diff 工具。以下步驟會帶領你走完整個工作流程,從準備輸入到處理輸出。

  1. 準備兩份嚴格的 JSON 文件。兩份輸入都必須能依據 RFC 8259 通過解析,因此在貼上之前,請先移除任何註解、尾端逗號、未定義值、NaN、Infinity、BigInt 字面值或 JavaScript 物件語法。如果不確定能否乾淨解析,可以將兩端分別跑過 JSON 驗證器JSON 格式化工具
  2. 將較舊或左側的文件貼入左側輸入欄,將較新或右側的文件貼入右側輸入欄。格式與縮排不需要相符;只會比較解析後的結構,因此左側經過最小化、右側經過美化輸出是完全可接受的。
  3. 執行比較。JSON Diff 會解析兩端、以遞迴方式走訪它們,並產生一份確定性的差異清單。鍵會進行排序以利穩定回報,因此對相同輸入重新執行相同的比較,永遠會產生相同的輸出。
  4. 逐一檢視變更清單中的每個項目。對於每一個新增、刪除、變更或型別變更項目,請閱讀其 RFC 6901 JSON Pointer 路徑、變更種類,以及變更前後的值。型別相同但值不同的基本型別屬於「變更」,而型別發生切換的基本型別——例如數字變成字串,或 null 變成物件——則會被回報為「型別變更」。
  5. 複製變更清單以供審查。這份結構化輸出適合用於程式碼審查留言、工單更新或變更紀錄。在將清單貼到任何會被記錄或建立索引的地方之前,請先檢視其中敏感的變更前後值。
  6. 當需要自動處理變更清單時,請透過具備應用專屬測試的專用修補程式實作來套用變更。請將 JSON Diff 的結果視為兩份文件差異所在位置的權威性證據,而非可執行的計畫,因為該輸出本身並非 RFC 6902 JSON Patch。

文件的根目錄是空白的 JSON Pointer,在整個值發生變更時,在人類可讀的清單中會以 root 顯示。物件成員名稱內的斜線會被轉義為 ~1,而波字符號則轉義為 ~0,因此即使鍵內含保留字元,路徑也始終保持有效的 RFC 6901 參考。陣列位置使用十進位索引標記,因此根層級陣列的第三個元素會顯示為 /2,而非名稱。

解讀變更清單

輸出中的每個項目都會指明一個位置和一種差異類型。路徑告訴你差異出現在哪裡,附加的值則告訴你是什麼造成了這個差異。熟悉路徑語法是快速瀏覽冗長變更清單的最快方式,因為單一 JSON Pointer 在解析後的結構中只會指向恰好一個節點,無論其巢狀多深。

項目種類代表意義顯示的值
added(新增)鍵或陣列位置存在於右側但不存在於左側右側的值
removed(刪除)鍵或陣列位置存在於左側但不存在於右側左側的值
changed(變更)相同鍵或索引,相同 JSON 型別,但值不同左側與右側的值
type-changed(型別變更)相同鍵或索引,但 JSON 型別不同帶有型別標記的左側與右側值

由於物件鍵在回報前已進行排序,對相同輸入的兩次執行永遠會以相同順序列出子項差異。陣列項目會依其以零為基底的索引回報,這使得掃描因前端插入或刪除所造成的位移相當容易。如果某個值從一個索引移到另一個索引,結果會包含一筆刪除、一筆新增,或多筆變更項目,而非單一的語意移動,因為此工具不會猜測身分鍵、不會計算最長共同子序列對齊,也不會把陣列當作集合處理。

限制、邊界情況與注意事項

JSON Diff 強制設有明確的限制,並會直接失敗而非默默截斷較大的結果。每份輸入上限為 500,000 個字元,比較巢狀深度上限為 50 層,變更清單上限為 5,000 個項目。超出這些上限的輸入會在一開始就被拒絕,使輸出保持可審查的狀態,而非變成一份不完整且誤導的摘要。

數字會以 JavaScript Number 進行解析,這代表極大的整數與高精度的十進位數在比較開始前可能就已經被四捨五入。正零與負零會被視為相同的 JSON 數值,因此 0 和 -0 不會被視為差異。如果你的契約中精確的十進位表示法、任意精度數字,或 JSON 物件內重複的成員名稱具有關鍵意義,請改用具備為此情境設計的解析器與數值模型的工具來比較來源,而非仰賴這個瀏覽器型比較工具。

JSON 文字中重複的鍵是一種特殊情況。標準的 JSON 解析會在比較工具收到物件之前就解決這個問題,因此兩個同名成員無法作為獨立項目進行比較。如果你的資料格式允許重複的鍵,請在進行差異比較之前將其標準化為嚴格的 JSON。尾端註解、區塊註解、單引號字串以及其他非嚴格的 JSON 建構會被嚴格的 RFC 8259 解析器拒絕,並以剖析錯誤呈現,而非被默默略過。

在將變更清單複製到紀錄檔、工單或聊天對話之前,請先檢視其中敏感的值。輸出會在每個受影響的路徑上包含完整的變更前後值,這正是審閱者所需要的,但同時也正是秘密掃描工具不希望被寫下兩次的內容。

當 JSON Diff 不是合適的工具時

JSON Diff 是比較工具,而非轉換工具。其輸出是由產品定義的變更清單,包含變更前與變更後的值,而非 RFC 6902 JSON Patch、JSON Merge Patch、統一的文字差異或結構描述遷移。它不會產生 move、copy 或 test 操作,也不會聲稱被移除的值可在周圍變更後還原。

如果你的工作流程需要自動將變更套用至線上文件,請透過一個有維護的修補函式庫來執行變更清單,並搭配應用程式專屬的測試。如果你的資料格式允許註解式註記、尾端逗號或其他非嚴格 JSON,請先使用 JSON Formatter 或 JSON Validator 將其標準化。如果你需要以更一般性的方式(而非 JSON 結構)來比較兩個檔案,以行為基礎的 Diff Checker 會是更直接的選擇。

對於常與 JSON 比較一同進行的相關工作,JSON Formatter 可在貼上之前標準化縮排,而通用的 Linux 檔案差異工作流程 則涵蓋了比較任意文字檔案的更廣泛情境。當目標明確是要找出兩個 JSON 文件之間的結構性差異時,JSON Diff 便是專注且具確定性的選擇。

延伸閱讀:在 Notepad++ 中格式化 JSON 檔案:外掛與替代方案