去年下午,我花了一個下午的時間調試了一個同事發誓是正確的 Helm 值檔案。每個鍵看起來都正確。服務拒絕啟動。罪魁禍首是四個角色: NO 作為區域列表中未引用的國家/地區代碼。 YAML 解析器將其讀作布林值 false,渲染的模板 false 進入標頭後,該請求在下游被拒絕,並帶有錯誤訊息,該訊息既沒有提到 YAML 也沒有提到挪威。這個錯誤已經足夠出名了,以至於有一個名字--挪威問題--而且它只是等待我們大多數人視為"的格式的一系列驚喜之一;JSON 具有更好的空格。"
TL;DR: 的 yaml 到 json 轉換器 解析 YAML 文件並列印等效的 JSON,一路上解析錨點、別名、合併鍵和區塊標量。將您的配置視為 JSON,會向您準確顯示解析器在解釋到達叢集之前決定您的值的含義 - 它推斷出哪些類型,擴展引用它。它完全在您的瀏覽器中運行。
將 YAML 轉換為 JSON 不僅是格式變更。這是對您的配置實際包含的內容最快的可用審核。 JSON 沒有註解、沒有錨點、除了語法完全說明之外沒有隱式輸入,因此清單的 JSON 視圖是其已解析的、明確的版本。本指南涵蓋了 YAML 如何對應到 JSON、導致真實事件的類型和參考行為,以及在偵錯配置、根據清單編寫腳本或編寫測試夾具時如何使用轉換器。
將 YAML 轉換為 JSON 實際上有什麼作用?
這種關係是定義的,而不是偶然的: YAML 1.2 規範 聲明 YAML 是 JSON 的超集,因此每個 JSON 文件都已經是有效的 YAML。 YAML 和 JSON 描述了相同的三件事:將鍵映射到值、有序序列和標量。轉換遍歷 YAML 文件並發出其 JSON 等效項中的每個構造。區塊映射變成一個物件。區塊序列變成一個數組。標量變成字串、數字、布林值或空,取決於 YAML 核心模式如何解析它。
結構部分很無趣,因為它是機械的。有趣的部分是 YAML 可以表達的一切,而 JSON 無法表達,因為這就是轉換器必須代表您做出決定的地方:
| YAML 功能 | JSON 得到什麼 | 為什麼這很重要 |
|---|---|---|
評論 (# ...) |
掉了 | JSON 沒有註解語法;配置中的文檔無法保存 |
錨點和別名 (&base, *base) |
擴充副本 | JSON 沒有參考語法,因此共享區塊是重複的 |
合併鍵 (<<: *base) |
壓扁到物體中 | 根據合併金鑰規範,顯式金鑰覆蓋合併的金鑰 |
| 塊標量(` | , >`) |
一條帶有轉義的字串 |
多個文檔 (---) |
一系列文檔 | Kubernetes 叢變成 JSON 數組,每個資源一個元素 |
| 隱式打字 | 解析類型 | 未引用 8080 變成一個數字, true 一個布林值, null 一個空 |
最後一行是值得關注的。 JSON 強制每個值透過語法聲明其類型:引用平均字串,裸數字平均數字。 YAML 從文字形狀推斷類型。轉換為 JSON 使推論可見。如果您需要版本字串,JSON 會向您顯示 1.1 YAML 說的地方 1.10,您發現了一個錯誤,否則您可能會出貨。
為什麼 YAML's 隱式類型會導致真正的中斷
YAML 1.2 核心模式透過模式解析未引用的標量。數字變成整數。具有小數點或指數的數字變成浮點數。 true 和 false 成為布林值。 null 和 ~ 變為空。其他一切都是一個字串。
這聽起來很整潔,直到您滿足看起來像一種類型並且意味著另一種類型的值:
- 連接埠和 ID。
port: 08080不是數字 8080。前導零使其成為核心模式下的無效整數,因此大多數解析器都會交回字串,而一些較舊的解析器會將其解釋為八進制。郵遞區號、電話號碼和帶有前導零的帳戶 ID 也有相同的問題。 - 版本。
version: 1.10是浮子1.1. 後面的零消失了,沒有解析器警告你。將其與容器標籤進行比較,查找失敗。 - 國家和語言代碼。 在 YAML 1.1 下 - 預設情況下,PyYAML 仍然遵循它,以及許多 Ruby 和較舊的 Java 工具 -
y,n,yes,no,on, 和off是布林值。NO,ON, 和NA是現實世界中完全普通的兩個字母代碼。 - 時間和六十進制。 YAML 1.1 也進行了解析
12:30作為以 60 為底的數字,即 750。類似 Cron 或類似持續時間的字串可以消失為整數。
其中每一個都是無聲的資料損壞,而不是解析錯誤。文件有效,管道是綠色的,值是錯誤的。轉換器's 保留字串 對於此類調查,存在選項:打開它,每個普通標量都會以字串形式返回,因此您可以並排比較兩次轉換,並準確地查看解析器正在重新解釋的值。無論 JSON 顯示什麼沒有該選項的內容,都是您的生產解析器今天最有可能做的事情。
來源 YAML 中的修復始終相同:引用任何具有文字含義的內容。 port: "8080", version: "1.10", region: "NO". 報價無需花費任何費用,並刪除整個類別的錯誤。如果您從 JSON 產生 YAML 而不是編寫它,則 JSON 到 Yaml 轉換器 自動將引用應用於不明確的值。
錨點、別名和合併鍵如何轉換
錨是 YAML'對重複的回答。您用 標記一個節點 &name,然後稍後再參考 *name:
defaults: &defaults
restartPolicy: Always
terminationGracePeriodSeconds: 30
web:
<<: *defaults
replicas: 3
worker:
<<: *defaults
terminationGracePeriodSeconds: 120
JSON沒有辦法說"與那邊相同的值。"因此轉換器將每個引用擴展為完整的副本。上面的輸出變成三個對象,每個對象都有自己的 restartPolicy,而且 JSON 比產生它的 YAML 更長。這不是轉換中的缺陷 - 這就是 YAML 的含義,寫出來。
合併密鑰 << 值得關注,因為它的優先規則很容易向後退。子映射中明確編寫的鍵戰勝了合併拉入的鍵。在範例中 worker 最終寬限期為 120,而不是 30,無論合併行出現在顯式鍵的上方還是下方。轉換器實現了該規則,因此 JSON 向您顯示有效的合併後配置 - 這通常是您實際想要檢查的內容。
由此得出兩個實際用途。首先,當配置使用重錨時,轉換為 JSON 是回答 " 的最快方法;這個環境實際上解決了什麼問題? &引用;不執行部署。其次,如果別名沒有匹配的錨點(將一個大文件分成多個大文件的常見結果),轉換器會將其報告為行號的錯誤,而不是默默地產生空值。
區塊標量如何轉換
YAML 有兩種嵌入多行文字的方法,而且它們的行為不同:
- 字面意思 (
|) 保持每條換行符完全按照書寫方式進行。將其用於 shell 腳本、PEM 憑證、SQL 以及任何對空白敏感的內容。 - 折疊 (
>) 將連續行與單一空格連接起來,並將空白行視為段落中斷。將其用於您想要包裝在原始檔案中但加入到值中的散文。
兩者都接受一個控制尾隨換行符的咀嚼指示符。預設值稱為剪裁,恰好保留一條尾隨換行符。 A 減號 (|-) 剝離所有尾隨換行符。 A 加 (|+)保留每一個。
在 JSON 中,所有這些都折疊成一條字串 \n 逃脫。這是 JSON 視圖有用的另一個原因:它是明確的。 A | 最後一行意外縮排的區塊,或 > 將兩條線折疊連接的區塊在 JSON 中很明顯,而在 YAML 中幾乎看不見。轉換器還處理捕獲簡單實現的情況 - a # 文字區塊中的字元是內容,而不是評論,當您嵌入以 shebang 開頭的 shell 腳本時,這很重要。
如何使用 YAML 到 JSON 轉換器
第 1 步:貼上文件
將任何 YAML 貼到輸入面板中:Kubernetes 清單,a docker-compose.ymlgithub Actions 工作流程、Ansible 劇本、a .gitlab-ci.yml,或應用程式配置。多文檔文件 --- 分隔符號很好 - 每個文件都是獨立解析的。點擊 載入樣本 從實際的部署開始,練習嵌套映射、序列、空集合和文字區塊標量。
一件無法解析的事情是用製表符縮排。 YAML 完全禁止製表符,轉換器會用違規行號而不是猜測來表示。在 Enter 上插入選項卡的編輯器是通常的來源;大多數都有一個 "將縮排轉換為空格和引用;立即修復整個檔案的命令。
步驟2:選擇輸出形狀
選擇 2 個空間, 4 個空間,或者 縮小. 當您即將將結果貼上到 a 中時,您想要的是縮小版 curl 身體或環境變數。縮排輸出是人類必須讀取它時想要的。
對鍵進行排序 在每個層級上按字母順序重寫物件鍵。在比較配置的兩個版本時,這是非常寶貴的:僅在鍵順序上不同的兩個檔案會產生相同的排序 JSON,因此差異僅顯示真實的變化。將兩個輸出饋送到 JSON 差異 工具,您可以獲得精確的結構比較,而不是逐行的比較。
保留字串 禁用標量強制,如上所述。當您想要查看每個值的原始文本時,或者當下游消費者無論如何都將所有內容視為字串時,請使用它。
第 3 步:轉換並讀取錯誤
單擊 折 折. 如果文件格式良好,JSON 會顯示在下面,以及行數、鍵數、位元組大小,以及(對於多文件流)找到了多少文件。
如果格式不正確,則錯誤命名該行。這些訊息涵蓋了實踐中實際發生的故障:用於縮排的選項卡、與其兄弟項不一致縮排的行、未終止的引用字串、沒有錨點的別名、指向非映射的項目的合併鍵。行號將五分鐘的搜尋變成五秒的修復。
第四步:複製、下載或繼續
將 JSON 複製到剪貼簿或下載為 .json 文件。從那裡開始,常見的後續步驟是漂亮列印和驗證 json 格式化程式,為配置載入器產生類型 json 到打字稿,或匯出 CI 驗證合約 JSON 模式產生器.
這適合真實的工作流程
調試清單 "看起來不錯"
當部署行為出乎意料且 YAML 讀取正確時,請將其轉換。 JSON 十分之九會立即顯示問題:一個值變成布林值,一個嵌套金鑰,由於雜散空間而比預期淺一級,一個擴展為陳舊內容的錨點。 JSON 視圖消除了使錯誤不可見的空白歧義。
針對配置編寫腳本
Shell 和 Node 腳本本機處理 JSON; YAML 需要依賴項。當我需要從一束清單中提取每個影像標籤時,請先轉換為 JSON 並透過管道傳輸 jq 比將 YAML 庫新增至一次性腳本更快。轉換器'這裡的多文檔支援很重要 - 由六個資源組成的 Kubernetes 捆綁包將成為您可以迭代的 JSON 陣列。
建築測試裝置
整合測試通常需要配置物件而不是配置檔案。將真實清單轉換為 JSON 可以為您提供保證匹配生產形狀的夾具,這是比您從記憶體中輸入的物件更好的起點。與之配對 json 到打字稿 您的燈具附帶類型。
查看拉取請求中的配置
重錨 YAML 的差異很難閱讀,因為一行更改為錨會默默地改變每個消費者。轉換兩個版本 對鍵進行排序 啟用和擴散 JSON 顯示真實的爆炸半徑:每個已解析的值都會發生變化,而不僅僅是編輯的線。
在工具之間遷移
許多平台接受 JSON,但不接受 YAML,反之亦然。轉換通常是整個遷移。當您需要以相反的方式返回時 - 手頭上有 JSON,需要 YAML - JSON 到 Yaml 轉換器 關閉循環,並且 yaml 驗證器 在提交之前確認結果解析。
YAML 和 JSON 進行了比較
| 維度 | 亞姆爾 | 傑森 |
|---|---|---|
| 評論 | 是的 | 不 |
| 人工編輯 | 基於縮排,易於撇取 | 標點符號重,冗長 |
| 機器解析 | 更慢、更大的解析器、更多的邊緣情況 | 到處都是快速、微小的解析器 |
| 類型推論 | 隱式、模式相關 | 從語法中顯式 |
| 參考文獻 | 錨點、別名、合併鍵 | 沒有 |
| 每個文件多個文件 | 是的,透過 --- |
不 |
| 典型的家 | 配置檔案、CI 管道、清單 | API、資料交換、儲存 |
YAML 1.2 在形式上是 JSON 的超集,因此每個 JSON 文件都已經是有效的 YAML。反之則不然,這就是為什麼將 YAML 轉換為 JSON 是一個方向的有損操作:註解和參考結構被丟棄,而資料被保留。如果您的 YAML 有您關心的評論,請保留 YAML 作為事實來源,並將 JSON 視為派生工件。
隱私:為什麼它會在您的瀏覽器中運行
配置檔案是團隊擁有的最敏感的純文字工件之一。它們攜帶內部主機名稱、叢集名稱、註冊表路徑、服務帳戶、資料庫標識符,以及 - 儘管每個人'最好的意圖 - 偶爾提供尚未成為秘密管理器的憑證。
轉換器是客戶端 JavaScript。您的文件在頁面中解析,JSON 在頁面中生成,並且沒有任何請求將您的資料帶到任何地方。載入該工具一次,它就會繼續關閉網絡,這對於您貼上清單的任何內容來說都是一個合理的習慣。這是網站上每個工具背後的相同原則,推理在指南中詳細說明 線上工具中的資料隱私. 如果您正在組裝通用瀏覽器工具包,則 web 開發人員工具包 指南涵蓋了其中其他內容。
限制值得了解
適合瀏覽器標籤的轉換器無法實現 YAML 規範的每個角落,並且具體說明邊緣比暗示沒有邊緣更有用。
複雜的映射鍵 - 顯式 ? key 不支援鍵本身是序列或映射的形式,因為 JSON 物件鍵必須是字串。鍵入標籤,例如 !!binary 或定制 !MyType 指令不被解釋;該值以文字形式出現。特殊浮點值 .inf, -.inf, 和 .nan 被保留為字串,因為 JSON 沒有它們的文字並默默地轉換為 null 失去的資訊多於保存的資訊。指令,例如 %YAML 1.2 被忽視而不是採取行動。
這些都沒有出現在普通的 Kubernetes、Compose、Actions 或 Ansible 檔案中。如果您擊中了其中一個,則您正在使用為特定語言編寫的文件's YAML 庫,以及該庫'自己的轉儲器是正確的工具。
問號
如何將 yaml 轉換為 json 線上?
將您的 YAML 貼到輸入面板中,然後按一下轉換。 解析器讀取文件,解析錨點和區塊標量,並列印您可以複製或下載的格式化 JSON。 瀏覽器中的所有內容都發生,因此沒有上傳檔案。
JSON 是 YAML 的子集嗎?
是的。 YAML 1.2 被重新定義為 JSON 的嚴格超集,因此任何有效的 JSON 文件也是有效的 YAML。 反之亦然:YAML 新增註解、錨點、區塊標量、每個檔案的多個文件和非字串鍵,JSON 都不能直接表達。
YAML 錨和別名如何轉換為 JSON?
JSON 沒有參考語法,因此每個別名都擴展為其錨定義的值的完整副本。重複使用預設區塊 3 次的配置會產生三個相同的 JSON 物件。因此,輸出大於 YAML 來源,但語意相同。
像雙角支架這樣的合併鍵會發生什麼事?
引用的映射被合併到目前的物件。 在子映射中明確編寫的金鑰戰勝了合併的金鑰,這與 YAML 合併金鑰規範以及 Kubernetes 和 Ansible Tooling 的行為相符。
為什麼我的 YAML 因選項卡錯誤而失敗?
YAML 禁止使用選項卡字元進行縮排 - 此規範僅允許空格。在 Enter 上插入選項卡的編輯器是常見的原因。將前導選項卡轉換為空格,大多數編輯器可以立即對整個文件執行此操作,並且文件將解析。
我可以使用文件分隔符號轉換多文件 YAML 檔案嗎?
是的。分隔符號之間的每個文件都是獨立解析的,結果是一個 JSON 數組,每個文件都有一個元素,按來源順序排列。單一文件檔案傳回物件本身,而不是單元素數組。
連接埠號碼和版本字串會保持它們的類型嗎?
普通標量由 YAML 核心模式解析,因此未引用的 8080 變成數字 8080,未引用的 1.10 變成 1.1。引用 YAML 中的值以將其保留為字串,或開啟「保留字串」選項以關閉所有標量強制。
文字標量和折疊塊標量如何轉換?
文字區塊保留每條換行符,因此它變成帶有轉義換行符的 JSON 字串。折疊塊將帶有空格的連續行連接起來,並將空白行視為段落中斷。尊重重擊指示符:減號刪除尾隨換行符,加號保留每條尾隨空白行。



