繁體中文

語法轉換器的作用

JSON、YAML、XML、TOML 和 CSV 不包含相同的內容。此頁面準確說明了每個形狀的映射方式、哪些轉換是有損的,以及該工具拒絕執行哪些操作。

它轉換什麼

九種定向轉換:JSON 到 YAML、YAML 到 JSON、JSON 到 XML、XML 到 JSON、JSON 到 TOML、TOML 到 JSON、YAML 到 TOML、TOML 到 YAML 以及 JSON 到 CSV。每個都在您的瀏覽器標籤中運行;沒有上傳任何內容。

每個轉換在內部都以相同的方式運作:將來源文件讀入普通的 JavaScript 值,然後以目標格式寫出該值。 YAML 到 TOML 並不是一個特例,它是 YAML 讀取器隨後是 TOML 寫入器。這就是為什麼下面的警告是按格式而不是按對聲明的 - 有關 TOML 日期時間的警告適用於 TOML 出現的任何地方。

CSV 是只寫的,而且是故意這樣的。讀取 CSV 意味著猜測分隔符號、引用方言、第一行是否是標題以及每個單元格的類型——四次猜測,每一次轉換器都會悄悄出錯。這是一個有要求的工具的工作。

XML:屬性、陣列和我們選擇的規則

XML 沒有規範的 JSON 映射,因此必須選擇約定。只要 XML 是這兩種格式之一,它們就在螢幕上可見,它們就是這些。

屬性成為以 @ 為前綴的物件鍵。 <user id="7"><name>Ada</name></user> 讀作 {"user":{"@id":"7","name":"Ada"}}。前綴可以防止同名的屬性和子元素折疊成一個鍵 - <user id="7"><id>other</id></user> 保留兩者。

也具有屬性或子元素的元素內的文字位於#text 鍵下。僅包含文字的元素會折疊為該文字。 CDATA 部分位於 #cdata 下,因此其內容顯然是資料而不是標記。

重複的同級元素成為一個陣列。出現一次的元素名稱不會變成陣列 — XML 使解析器無法區分“包含一項的清單”和“單一值”,並且沒有轉換器可以發明該資訊。如果您需要穩定的形狀,那麼這是模式的爭論,而不是更聰明的轉換器的爭論。

命名空間前綴逐字保留:<ns:item> 是鍵 ns:item,xmlns:ns 是屬性 @xmlns:ns。沒有任何內容被解析​​、重寫或剝離,因為解析前綴會丟棄文件實際包含的文字。

自閉合標籤讀作空字串。 XML 聲明、處理指令和註解均被刪除。另一方面,該工具編寫自己的聲明,而不是 DOCTYPE。

編寫 XML 時,如果鍵不是合法的 XML 元素名稱(一個帶有空格,一個以數字開頭,一個以字母 xml 開頭),則會按名稱拒絕,而不是默默地重寫。悄悄重新命名的元素會產生一個沒有任何驗證的文件。

外部實體被拒絕,而不僅僅是被禁用

XML 文件可以聲明 DOCTYPE 中的實體。擴展它們的解析器是 XXE 漏洞:聲明為 SYSTEM“file:///etc/passwd”的實體讀取本地文件,指向 URL 的實體發出攻擊者控制的請求,而內部實體鍊是將幾百字節變成千兆字節的“十億笑聲”拒絕服務。

此轉換器不會將解析器配置為小心 DOCTYPE。在給解析器一個位元組之前,它會拒絕任何包含該位元組的文檔,並且沒有選項可以關閉拒絕。這使得保證成為我們程式碼的屬性,而不是依賴項的預設值 - 並且差異很重要,因為版本之間的預設值會發生變化,並且我們自己的拒絕被測試覆蓋,這些測試為它提供每個標準 XXE 有效負載,並斷言沒有獲取任何內容,也沒有擴展任何內容。

實際成本:具有 DOCTYPE 的文件即使無害,也不會在此進行轉換。如果內容是您的,請刪除 DOCTYPE。

TOML 日期時間在其他地方沒有等效項

TOML 1.0 有四種時間類型,而 JSON、YAML 和 XML 沒有:偏移日期時間 (1979-05-27T07:32:00Z)、本地日期時間 (1979-05-27T07:32:00,故意沒有區域)、本地日期 (1979-05-207:207

每個都變成與編寫時完全相同的 RFC 3339 字串,並且轉換會告訴您它對哪些值執行了此操作以及每個值屬於四種類型中的哪一種。另一個選擇是為所有四個時間發出一個 UTC 時刻,將當地時間移動到文件明確拒絕聲明的區域,這是一個錯誤的答案,而不是一個有損的答案。

轉換回來會產生引號的字串,而不是日期時間。因此,TOML 到 JSON 到 TOML 的往返會改變這些值的類型。如果不發明一種接收工具必須共享的約定,就無法解決這個問題,而默默地發明一種約定會更糟。

TOML 整數有符號 64 位元;JSON 數字是 IEEE-754 雙精確度數。超過 2^53 - 1 的整數將成為一個字串,並在警告中指定路徑,而不是因舍入而丟失最後一位數字,而您不會注意到。

TOML 沒有 null。輸出中省略了空鍵並在警告中命名;數組中的 null 會變成空字串,因為刪除它會移動後面的每個索引。 TOML 文件的根總是一個表,因此根處的陣列或裸值會被拒絕,並用一句話說明原因。

YAML:錨點、流和挪威問題

YAML 使用受限模式讀取,只能產生字串、數字、布林值、null、列表和映射。建構任意物件的標籤 - !!js/function、!!python/object/apply、!!binary - 被拒絕,這就是限制存在的全部原因:尊重它們的載入器是一個穿著設定檔衣服的任意物件建構函式。

錨點和別名被解析為重複的資料。一旦跟隨其別名,文件的值就會擴展超過一百萬個值,該文件將被拒絕,而不是允許凍結選項卡;遞歸別名被徹底拒絕,因為這裡沒有其他格式可以表達循環。

由 --- 分隔的多個文檔的流成為文檔數組,轉換也是如此。此工具中沒有其他格式具有流,因此數組是唯一誠實的映射。

YAML 禁止重複的映射鍵,且每個解析器的處理方式都不同。該工具保留最後一個值(JSON.parse 使用的規則)並告訴您它發生了,以及重複的位置。默默地丟棄文件會更糟;默默地選擇一個值而不說出來會更糟。

挪威問題:在 YAML 1.1 中,未加引號的標量 y、yes、on、no、off 和國家/地區代碼 NO 都解析為布林值,這是國家代碼列表變成 true 和 false 列表的方式。該工具讀取 YAML 1.2,其中只有 true 和 false 是布林值,因此 NO 保留字串 NO。當它編寫 YAML 時,它會引用 1.1 解析器會誤讀的每個字串 - 'NO'、'yes'、'on'、'1.0'、'0755'、'2001-12-14' - 因此輸出可以安全地提供給尚未遷移到 1.2 的工具。這會花費一些引號字元併購買正確性。

看起來像數字的字串出於同樣的原因保留其引號:「0755」保留字串而不是成為 755,「1.0」保留字串而不是成為 1。

評論在各方面都消失了。 JSON、CSV 等沒有地方放它們,也無法猜測它們應該返回哪裡。

JSON 到 CSV:扁平化和停止公式的撇號

數組變成行,每個元素一筆記錄。其單一屬性包含數組的物件使用該數組作為行,因為 {"users": [ ... ]} 絕大多數是帶有標籤的表 - 並且轉換大聲表明它做到了這一點。任何其他物件都是單行。拒絕裸露的字串、數字或空值:矩形需要記錄。

巢狀物件和陣列被展平為點列名稱,其中物件鍵和陣列索引都以點表示:address.city、tags.0、tags.1。一個分隔符,一條規則。已經包含點的鍵使其列名與嵌套路徑不明確;該工具會發出警告,而不是發明一個電子表格無法理解的轉義方案。

每一行的鍵都依照首次出現的順序聯合起來。缺少欄位的行會得到一個空白儲存格而不是移位的列,並且轉換會警告行不規則。一個空物件或空數組將成為其自己路徑下的一個空單元格,而不是消失。

引用遵循 RFC 4180:包含分隔符號、雙引號、CR 或 LF 的欄位用雙引號括起來,嵌入的引號會寫入兩次。記錄由 CRLF 分隔。帶有前導或尾隨空格的欄位也會被引用,因為電子表格會默默地修剪它們。 Unicode 不變地通過,並且可以為需要讀取 UTF-8 的電子表格添加位元組順序標記作為前綴。

配方注射劑是最痛苦的一種。當檔案開啟時,以 =、+、-、@、製表符或回車符開頭的儲存格將由 Excel、LibreOffice Calc 和 Google Sheets 作為公式執行。 =cmd|'/c calc'!A1 是大家引用的演示; =IMPORTXML(...) 是悄悄地將工作表送到某處的那個。逐字寫入此類字串的轉換器已將您的資料轉換為其他人的程式碼執行,在一個看起來惰性的檔案中。

因此,以這些字元之一開頭的文字儲存格帶有撇號前綴,每個主要電子表格都將其讀作“這是文字”,並且不會顯示在儲存格中。數字不用管:數字 -5 是一個數字,而不是一個公式。報告逃逸單元的計數,並且可以關閉逃逸 - 在這種情況下,該工具會清楚地說明您剛剛關閉的內容。

CSV 無法區分空字串和 null。兩者都變成空單元格,並且轉換會計算空值,以便您知道它發生了。

限制以及當您達到限制時會發生什麼

每種格式都有字元上限,在下載解析器之前就強制執行:JSON 為 8 百萬,XML 和 CSV 來源為 4 百萬,YAML 和 TOML 為 2 百萬。除此之外,該工具會拒絕提供確切的數字,而不是成為一個無回應的選項卡,從而丟失您貼上的內容。

CSV 輸出也受到 100,000 行和 2,000 列的限制,因為深度巢狀的陣列會展平為每個元素一列,而幾兆位元組的 JSON 可能會成為電子表格無法開啟的表格。

空和僅空白輸入將報告為空,而不是轉換為 null 或空文檔。所有四種可讀格式中的行和列都會報告無效語法。

只有當轉換需要解析器時才會下載解析器本身。開啟工具包來解碼 JWT 不會取得任何內容。

你貼的內容會發生什麼

  • 每個轉換、哈希、解碼和差異都在您的瀏覽器標籤中運行。不會在伺服器上傳、記錄或儲存任何輸入,因為頁面載入後就不再涉及伺服器。
  • 雜湊值來自瀏覽器自己的 Web Crypto 實現,UUID 來自其加密安全隨機產生器。兩者都不涉及網絡調用。
  • 您鍵入的任何內容都不會寫入本機儲存或 cookie。重新載入頁面會丟棄它;關閉選項卡將丟棄它。
  • 站點範圍的分析僅在配置的規範生產主機上運行,並在隱私權政策中披露;本地和預覽主機拒絕它。貼上的值、令牌、URL 和文件內容不包括在 ToolAcre 自己的分析事件中。目前配置中停用廣告。
  • 也就是說:JWT 或 API 金鑰是即時憑證。安全的習慣是永遠不要將其粘貼到不是您編寫的網頁中,無論其聲明多麼可信 - 包括這個。

問題

為什麼我的 XML 文件失敗並顯示“聲明 DOCTYPE”?

因為它包含文件類型聲明,並且此轉換器拒絕其中的每一個,而不是信任解析器設定來安全地處理實體。如果內容是您的,請刪除 DOCTYPE。沒有選項允許它。

為什麼我的 TOML 日期時間會傳回為引號的字串?

因為 JSON、YAML 和 XML 沒有日期類型。日期時間被轉換為 RFC 3339 文本,它是所有其他格式的字串。因此,轉換回來會產生一個字串,並且該工具會在發生這種情況時向您發出警告,而不是讓您稍後發現。

為什麼我的 CSV 單元格之一以撇號開頭?

因為它的文字以=、+、-、@、製表符或回車符開頭,而電子表格在開啟檔案時將此類儲存格作為公式執行。撇號將儲存格標記為文字;一旦儲存格被讀取,它就不再是值的一部分。您可以關閉轉義,該工具會告訴您這意味著什麼。

為什麼單一重複的 XML 元素不是數組?

因為 XML 無法提供區分一列表和單一值的方法。兩者寫法相同。在任何一個方向上進行猜測都有可能是錯誤的,因此該工具會報告實際存在的內容。

我可以在這裡將 CSV 轉換回 JSON 嗎?

不能。正確讀取 CSV 需要決定分隔符號、引用方言、第一行是否為標題以及每個儲存格的類型。猜測所有四個的轉換器都會悄悄地出錯,這是最糟糕的錯誤方式。使用要求的 CSV 工具。

為什麼 "NO" 沒有轉換為 false?

因為該行為屬於 YAML 1.1 並此工具讀取 YAML 1.2,其中只有 true 和 false 是布林值。 1.1 行為是挪威國家/地區程式碼在組態管理中成為笑話的原因。當工具寫入 YAML 時,它會引用此類字串,因此下游的 1.1 解析器也不會誤讀它們。

限制

  • CSV 是寫入的,從未讀取過。這裡沒有選擇將 CSV 轉換為 JSON。
  • 評論在各個方向、各種格式都會遺失。
  • TOML 日期時間變成所有其他格式的字串,因此 TOML 往返會變更這些類型。不存在無損路徑。
  • 包含 DOCTYPE 的 XML 文檔將被徹底拒絕,包括無害的文檔,並且拒絕無法關閉。
  • 單一重複的 XML 元素無法與非重複的元素區分開來,因此 XML 到 JSON 到 XML 並不總是會傳回原始形狀。
  • XML 混合內容(與子元素交錯的文字)會遺失文字相對於子元素的位置,且無法往返。
  • 除非開啟類型推斷,否則 XML 值都是字串,因為 XML 不宣告任何類型;透過推理,"0755" 和 "NO" 會受到通常的誤讀。
  • TOML 沒有 null:空鍵從 TOML 輸出中刪除,陣列內的 null 變成空字串。
  • TOML 文件的根必須是表,因此 JSON 陣列或標量根本無法轉換為 TOML。
  • JSON 數字是 IEEE-754 雙精度數。 2^53 之後的整數將轉換為字串,而不是靜默捨入,這會改變它們的類型。
  • CSV 無法區分空字串和 null;兩者都寫為空單元格。
  • CSV 扁平化對物件鍵和陣列索引都使用點,因此已經包含點的鍵會產生不明確的列名稱,該名稱會被警告但不會轉義。
  • YAML 錨點和別名被解析而不是保留;輸出沒有錨點,並且拒絕遞歸別名,因為沒有目標格式可以表達循環。
  • 每種格式的輸入都有上限——JSON 8 百萬個字符,XML 4 百萬個字符,YAML 和 TOML 2 百萬個字符——並且過大的文檔會被拒絕而不是緩慢處理。
  • 這裡沒有任何內容根據模式進行驗證。文件可以乾淨利落地轉換,但對於其目的來說仍然是錯誤的。