雜記 › 技術筆記 › JSON 太長找不到欄位?樹狀檢視折疊和搜尋定位

JSON 太長找不到欄位?樹狀檢視折疊和搜尋定位

上週查一個介面的回應,回應主體接近五萬字,全部壓在一行裡。我要找的欄位叫 "shop_name",用編輯器的尋找功能打進去,游標跳到第 3 萬個字元附近,但我看不見它在哪個物件裡、是第幾筆記錄,也不敢確認命中是鍵名還是某個同名的值。那次之後我給自己定了個規矩:讀 JSON 先讓它變成結構,再談找東西。

格式化只解決「撐開」,不解決「在哪」

把一行拆成縮排的多行,是很多人的第一步。這一步確實有用,可讀性立刻提升。但它給不了你層級感:縮排 12 層的檔案靠肉眼數空格很沒效率,而且展開之後行數從 1 行變成幾千行,捲動反而更慢。

我現在的做法是直接把資料丟進 JSON 檢視。每個物件和陣列變成一個可收合的節點,展開或收起來都行,也能全部展開、全部收合。找欄位這件事的本質就變了:不再是「掃過多少行文字」,而是「在哪些分支裡搜」。

型別顏色是我用得最多的第二個資訊。字串、數字、布林值、null 各用不同顏色區分,掃一眼就知道 "total": 20 是數字,"total": "20" 是字串——這兩者在介面裡長得一樣,出問題時行為完全不同。我在一次聯合除錯裡被 "status": null 和 "status": "" 折騰過很久,從那以後先看顏色再讀值。

路徑寫法:層級、鍵名、陣列索引

巢狀結構要有名字才能溝通。我的習慣是物件層級用點,陣列用方括號索引,索引從 0 開始。這樣一個欄位的位置就能寫成一條完整路徑,說給別人聽、貼進程式碼、寫進工單都是同一串字元。

舉個具體的結構:

{
  "code": 0,
  "data": {
    "list": [
      { "id": 101, "items": [ { "sku": "A-1", "name": "杯子" }, { "sku": "A-2", "name": "壺" }, { "sku": "A-3", "name": "盤" } ] },
      { "id": 102, "items": [ { "sku": "B-1", "name": "鍋" } ] }
    ],
    "page": { "no": 1, "size": 20, "has_more": false }
  }
}
路徑寫法 指向什麼 容易踩的點
data.page.size 數字 20 鍵名重複時只有一條路徑是對的
data.list[0].items[2].name 字串「盤」 索引從 0 數,第 3 筆要寫成 [2]
data.list[1].items[0].sku 字串「B-1」 陣列只有一筆時也可能被當成物件
data.list[0].items 整個陣列,3 個元素 收合時看起來像空節點,其實有內容

在樹裡點任意節點就能複製它的路徑,這一點替我省下大量手工抄寫的功夫。手工抄路徑的錯法很典型:索引偏了一位,測試時對著錯的物件查,最後以為介面沒回傳。

收合、搜尋、複製路徑,這三件事我分別什麼時候用

搜尋按關鍵字比對,鍵名和值都能命中,命中的地方會標亮,還能上一個、下一個地跳。我要判斷「這個欄位出現了幾次」時靠它,例如排查重複鍵名。

收合用在兩個方向。一個是排除:確認某個分支和我要找的東西無關,就把它收起來,剩下的可視區域立刻變小。另一個是壓縮上下文:我關心 data.page,那就把 data.list 兩個元素全部收起,螢幕上只剩幾行。

複製路徑是給「輸出」用的。定位到欄位之後,我要把它變成程式碼裡的取值運算式、變成給後端的說明、變成測試案例裡的斷言目標,路徑字串就是中間那層通用語言。

至於純文字美化或壓縮回去,那是另一件事。要把 JSON 貼回程式碼或縮小體積時我用 JSON 格式化;樹狀檢視負責讀,格式化負責寫,我不再用格式化去代替定位。

還有一類需求搜尋框解決不了:我要找的是「所有以 _url 結尾的鍵」這種模式比對。關鍵字搜尋在這裡幫不上忙,我會把內容交給 正規表示式測試,先在純文字上把候選行撈出來,再回樹裡確認層級。

Q:為什麼我搜 "name" 命中的位置跟我要找的欄位不一樣?

因為 "name" 在巢狀結構裡出現很多次,命中順序只是文字位置的順序。先看有幾處命中,再用上一個、下一個逐個跳,配合收合排除無關分支。

Q:樹狀檢視和格式化,只需要一個嗎?

看資料用檢視,改資料用格式化。檢視給的是結構與路徑,格式化給的是可貼上的文字;兩個方向相反,用一個替另一個會很彆扭。

Q:很長的陣列能不能只看前幾筆?

我的做法是收合掉不需要的那些元素,只展開關心的索引。逐個展開一千筆元素沒有意義,問題通常在個別索引上。

Q:介面回傳的 JSON 裡有中文和轉義字元,會看不準嗎?

值裡的轉義字元(例如 \n 和 \")在樹裡顯示的是字元本身,讀的時候把它當成原始字元理解就好;真的要處理轉義是寫程式碼那一步的事。

Q:資料涉敏,不敢往線上工具裡貼。

我的判斷標準是看它有沒有把內容送出去。這類工具如果只在瀏覽器本機處理,資料不出機器,敏感的回應主體我也敢直接貼;換成需要上傳的方案,我就改用本機編輯器加外掛。

那次找了半小時的 "shop_name",最後的答案是它在 data.list[1].items[0] 下面,而我要的那筆記錄在第 0 個元素裡——兩個都有同名字段,我一開始撞上的就是錯的那個。從那以後我先數命中處數,再決定展開哪一支,順序和以前完全反過來了,這大概是這類問題最實際的解法。

📎 相關文章

PNG 壓了三遍只減 426 位元組:無損壓縮的真實邊界 2026-10-22 WebP 轉 PNG 後體積漲了幾倍:什麼時候必須轉,怎麼把漲幅壓住 2026-10-22 截圖縮到四分之一,小字糊成一團的三種原因 2026-10-22 同樣裁 300×300,頭像為什麼總偏右下角半格 2026-10-22 按每月 1.7 倍預估 18 個月,腳本和表格為什麼給出兩個數 2026-10-22