JSON、XML、TOML、CSON、YAML大比拼
一段超級嚴肅的關于樣本序列化的集合、子集和超集的文字
我是一名開發(fā)者,我讀代碼,我寫代碼,我寫會寫代碼的代碼,我寫會寫出供其它代碼讀的代碼的代碼。這些都非?;鹦钦Z,但是有其美妙之處。然而,***一點,寫會寫出供其它代碼讀的代碼的代碼,可以很快變得比這段文字更費解。有很多方法可以做到這一點。一種不那么復雜而且開發(fā)者社區(qū)***的方式是數(shù)據(jù)序列化。對于那些不了解我剛剛拋給你的時髦詞的人,數(shù)據(jù)序列化是從一個系統(tǒng)獲取一些信息,將其轉(zhuǎn)換為其它系統(tǒng)可以讀取的格式,然后將其傳遞給其它系統(tǒng)的過程。
雖然數(shù)據(jù)序列化格式多到可以埋葬哈利法塔,但它們大多分為兩類:
- 易于人類讀寫,
- 易于機器讀寫。
很難兩全其美,因為人類喜歡讓我們更具表現(xiàn)力的松散類型和靈活格式標準,而機器傾向于被確切告知一切事情而沒有二義性和細節(jié)缺失,并且認為“嚴格規(guī)范”才是它們***的口味。
由于我是一名 web 開發(fā)者,而且我們是一個創(chuàng)建網(wǎng)站的機構(gòu),我們將堅持使用 web 系統(tǒng)可以理解或不需要太多努力就能理解的特殊格式,而且對人類可讀性特別有用的格式:XML、JSON、TOML、CSON 以及 YAML。每個都有各自的優(yōu)缺點和適當?shù)挠美龍鼍啊?/p>
事實***
回到互聯(lián)網(wǎng)的早期,一些非常聰明的家伙決定整合一種讓每個系統(tǒng)都能理解的標準語言,并創(chuàng)造性地將其命名為標準通用標記語言(簡稱 SGML)。SGML 非常靈活,發(fā)布者也很好地定義了它。它成為了 XML、SVG 和 HTML 等語言之父。所有這三個都符合 SGML 規(guī)范,可是它們都是規(guī)則更嚴格、靈活性更少的子集。
最終,人們開始看到非常小、簡潔、易讀且易于生成的數(shù)據(jù)的好處,這些數(shù)據(jù)可以在系統(tǒng)之間以編程的方式共享,而開銷很小。大約在那個時候,JSON 誕生了并且能夠滿足所有的需求。而另一方面,其它語言也開始出現(xiàn)以處理更多的專業(yè)用例,如 CSON,TOML 和 YAML。
XML:不行了
原本,XML 語言非常靈活且易于編寫,但它的缺點是冗長,人類難以閱讀、計算機非常難以讀取,并且有很多語法對于傳達信息并不是完全必要的。
今天,它在 web 上的數(shù)據(jù)序列化的用途已經(jīng)消失了。除非你在編寫 HTML 或者 SVG,否則你不太能在許多其它地方看到 XML。一些過時的系統(tǒng)今天仍在使用它,但是用它傳遞數(shù)據(jù)往往太重了。
我已經(jīng)可以聽到 XML 老爺爺開始在它們的石碑上亂寫為什么 XML 是了不起的,所以我將提供一個小小的補充:XML 可以很容易地由系統(tǒng)和人讀寫。然而,真的,我的意思是荒謬的,很難創(chuàng)建一個可以規(guī)范的讀取它的系統(tǒng)。這是一個簡單美觀的 XML 示例:
<book id="bk101">
<author>Gambardella, Matthew</author>
<title>XML Developer's Guide</title>
<genre>Computer</genre>
<price>44.95</price>
<publish_date>2000-10-01</publish_date>
<description>An in-depth look at creating applications
with XML.</description>
</book>
太棒了。易于閱讀、理解、寫入,也容易編碼一個可以讀寫它的系統(tǒng)。但請考慮這個例子:
<!DOCTYPE r [ <!ENTITY y "a]>b"> ]>
<r>
<a b="&y;>" />
<![CDATA[[a>b <a>b <a]]>
<?x <a> <!-- <b> ?> c --> d
</r>
這上面是 100% 有效的 XML。幾乎不可能閱讀、理解或推理。編寫可以使用和理解這個的代碼將花費至少 36 根頭發(fā)和 248 磅咖啡渣。我們沒有那么多時間或咖啡,而且我們大多數(shù)老程序員們現(xiàn)在都是禿頭。所以,讓它活在我們的記憶里,就像 css hacks、IE 6 瀏覽器 和真空管一樣好了。
JSON:并列聚會
好吧,我們都同意,XML = 差勁。那么,好的替代品是什么?JavaScript 對象表示法,簡稱 JSON。JSON(讀起來像 Jason 這個名字) 是 Brendan Eich 發(fā)明的,并且得到了偉大而強力的 JavaScript 意見*** Douglas Crockford 的推廣。它現(xiàn)在幾乎用在任何地方。這種格式很容易由人和機器編寫,按規(guī)范中的嚴格規(guī)則解析也相當容易,并且靈活 —— 允許深層嵌套數(shù)據(jù),支持所有的原始數(shù)據(jù)類型,及將集合解釋為數(shù)組或?qū)ο蟆SON 成為了將數(shù)據(jù)從一個系統(tǒng)傳輸?shù)搅硪粋€系統(tǒng)的事實標準。幾乎所有語言都有內(nèi)置讀寫它的功能。
JSON語法很簡單。方括號表示數(shù)組,花括號表示記錄,由冒號分隔的兩個值分別表示屬性或“鍵”(在左邊)、值(在右邊)。所有鍵必須用雙引號括起來:
{
"books": [
{
"id": "bk102",
"author": "Crockford, Douglas",
"title": "JavaScript: The Good Parts",
"genre": "Computer",
"price": 29.99,
"publish_date": "2008-05-01",
"description": "Unearthing the Excellence in JavaScript"
}
]
}
這對你來說應該是完全有意義的。它簡潔明了,并且從 XML 中刪除了大量額外廢話,并傳達相同數(shù)量的信息。JSON 現(xiàn)在是王道,本文剩下的部分會介紹其它語言格式,這些格式只不過是 JSON 的簡化版,嘗試讓其更簡潔或?qū)θ祟惛鬃x,可結(jié)構(gòu)還是非常相似的。
TOML: 縮短到徹底的利他主義
TOML(Tom 的顯而易見的最小化語言)允許以相當快捷、簡潔的方式定義深層嵌套的數(shù)據(jù)結(jié)構(gòu)。名字中的 Tom 是指*** Tom Preston Werner,他是一位活躍于我們行業(yè)的創(chuàng)造者和軟件開發(fā)人員。與 JSON 相比,語法有點尷尬,更類似 ini 文件。這不是一個糟糕的語法,但是需要一些時間適應。
[[books]]
id = 'bk101'
author = 'Crockford, Douglas'
title = 'JavaScript: The Good Parts'
genre = 'Computer'
price = 29.99
publish_date = 2008-05-01T00:00:00+00:00
description = 'Unearthing the Excellence in JavaScript'
TOML 中集成了一些很棒的功能,例如多行字符串、保留字符的自動轉(zhuǎn)義、日期、時間、整數(shù)、浮點數(shù)、科學記數(shù)法和“表擴展”等數(shù)據(jù)類型。***一點是特別的,是 TOML 如此簡潔的原因:
[a.b.c]
d = 'Hello'
e = 'World'
以上擴展到以下內(nèi)容:
{
"a": {
"b": {
"c": {
"d": "Hello"
"e": "World"
}
}
}
}
使用 TOML,你可以肯定在時間和文件長度上會節(jié)省不少。很少有系統(tǒng)使用它或非常類似的東西作為配置,這是它***的缺點。根本沒有很多語言或庫可以用來解釋 TOML。
CSON: 特定系統(tǒng)所包含的簡單樣本
首先,有兩個 CSON 規(guī)范。 一個代表 CoffeeScript Object Notation,另一個代表 Cursive Script Object Notation。后者不經(jīng)常使用,所以我們不會關注它。我們只關注 CoffeeScript。
CSON 需要一點介紹。首先,我們來談談 CoffeeScript。CoffeeScript 是一種通過運行編譯器生成 JavaScript 的語言。它允許你以更加簡潔的語法編寫 JavaScript 并轉(zhuǎn)譯成實際的 JavaScript,然后你可以在你的 web 應用程序中使用它。CoffeeScript 通過刪除 JavaScript 中必需的許多額外語法,使編寫 JavaScript 變得更容易。CoffeeScript 擺脫的一個大問題是花括號 —— 不需要它們。同樣,CSON 是沒有大括號的 JSON。它依賴于縮進來確定數(shù)據(jù)的層次結(jié)構(gòu)。CSON 非常易于讀寫,并且通常比 JSON 需要更少的代碼行,因為沒有括號。
CSON 還提供一些 JSON 不提供的額外細節(jié)。多行字符串非常容易編寫,你可以通過使用 #
符號開始一行來輸入注釋,并且不需要用逗號分隔鍵值對。
books: [
id: 'bk102'
author: 'Crockford, Douglas'
title: 'JavaScript: The Good Parts'
genre: 'Computer'
price: 29.99
publish_date: '2008-05-01'
description: 'Unearthing the Excellence in JavaScript'
]
這是 CSON 的大問題。它是 CoffeScript 對象表示法。也就是說你要用 CoffeeScript 解析/標記化/lex/轉(zhuǎn)譯或其它方式來使用 CSON。CoffeeScript 是讀取數(shù)據(jù)的系統(tǒng)。如果數(shù)據(jù)序列化的目的是允許數(shù)據(jù)從一個系統(tǒng)傳遞到另一個系統(tǒng),這里我們有一個只能由單個系統(tǒng)讀取的數(shù)據(jù)序列化格式,這使得它與防火火柴、防水海綿或者叉匙惱人的脆弱叉子部分一樣有用。
如果這種格式被其它系統(tǒng)也采用,那它在開發(fā)者世界中可能非常有用。但到目前為止這基本上沒有發(fā)生,所以在 PHP 或 JAVA 等替代語言中使用它是不行的。
YAML:年輕人的呼喊
開發(fā)人員感到高興,因為 YAML 來自一個 Python 的貢獻者。YAML 具有與 CSON 相同的功能集和類似的語法,有一系列新功能,以及幾乎所有 web 編程語言都可用的解析器。它還有一些額外的功能,如循環(huán)引用、軟包裝、多行鍵、類型轉(zhuǎn)換標簽、二進制數(shù)據(jù)、對象合并和集合映射。它具有非常好的可讀性和可寫性,并且是 JSON 的超集,因此你可以在 YAML 中使用完全合格的 JSON 語法并且一切正常工作。你幾乎不需要引號,它可以解釋大多數(shù)基本數(shù)據(jù)類型(字符串、整數(shù)、浮點數(shù)、布爾值等)。
books:
- id: bk102
author: Crockford, Douglas
title: 'JavaScript: The Good Parts'
genre: Computer
price: 29.99
publish_date: !!str 2008-05-01
description: Unearthing the Excellence in JavaScript
業(yè)界的年輕人正在迅速采用 YAML 作為他們***的數(shù)據(jù)序列化和系統(tǒng)配置格式。他們這樣做很機智。YAML 具有像 CSON 一樣簡潔的所有好處,以及與 JSON 一樣的數(shù)據(jù)類型解釋的所有功能。YAML 像加拿大人容易相處一樣容易閱讀。
YAML 有兩個問題,對我而言,***個是大問題。在撰寫本文時,YAML 解析器尚未內(nèi)置于多種語言,因此你需要使用第三方庫或擴展來為你選擇的語言解析 .yaml 文件。這不是什么大問題,可似乎大多數(shù)為 YAML 創(chuàng)建解析器的開發(fā)人員都選擇隨機將“附加功能”放入解析器中。有些允許標記化,有些允許鏈引用,有些甚至允許內(nèi)聯(lián)計算。這一切都很好(某種意義上),只是這些功能都不是規(guī)范的一部分,因此很難在其他語言的其他解析器中找到。這導致系統(tǒng)限定,你最終遇到了與 CSON 相同的問題。如果你使用僅在一個解析器中找到的功能,則其他解析器將無法解釋輸入。大多數(shù)這些功能都是無意義的,不屬于數(shù)據(jù)集,而是屬于你的應用程序邏輯,因此***簡單地忽略它們和編寫符合規(guī)范的 YAML。
第二個問題是很少有解析器完全實現(xiàn)規(guī)范。所有的基本要素都有,但是很難找到一些更復雜和更新的東西,比如軟包裝、文檔標記和***語言的循環(huán)引用。我還沒有看到對這些東西的剛需,所以希望它們不讓你很失望??紤]到上述情況,我傾向于保持 1.1 規(guī)范 中呈現(xiàn)的更成熟的功能集,而避免在 1.2 規(guī)范 中找到的新東西。然而,編程是一個不斷發(fā)展的怪獸,所以當你讀完這篇文章時,你或許就可以使用 1.2 規(guī)范了。
最終哲學
這是***一段話。每個序列化語言都應該以個案標準的方式評價。當涉及機器的可讀性時,有些無出其右。對于人類可讀性,有些名至實歸,有些只是金玉其外。以下是最終細分:如果你要編寫供其他代碼閱讀的代碼,請使用 YAML。如果你正在編寫能寫出供其他代碼讀取的代碼的代碼,請使用 JSON。***,如果你正在編寫將代碼轉(zhuǎn)譯為供其他代碼讀取的代碼的代碼,請重新考慮你的人生選擇。


2017-09-10 14:29:03
2011-11-08 10:29:44
2012-08-15 09:26:54




