YAML

功能

YAML的語法和其他高階語言類似，並且可以簡單表達清單、雜湊表，純量等資料形態。它使用空白符號縮排和大量依賴外觀的特色，特別適合用來表達或編輯資料結構、各種設定檔、傾印除錯內容、檔案大綱（例如：許多電子郵件標題格式和YAML非常接近）。儘管它比較適合用來表達階層式（hierarchical model）的資料結構，不過也有精緻的語法可以表示關聯性（relational model）的資料。由於YAML使用空白字元和分行來分隔資料，使得它特別適合用grep／Python／Perl／Ruby操作。其讓人最容易上手的特色是巧妙避開各種封閉符號，如：引號、各種括號等，這些符號在巢狀結構時會變得複雜而難以辨認。

簡單的檔案

資料結構可以用類似大綱的縮排方式呈現
---receipt:     Oz-Ware Purchase Invoicedate:        2012-08-06customer:
    given:   Dorothy
    family:  Gale
   
items:
    - part_no:   A4786
      descrip:   Water Bucket (Filled)
      price:     1.47
      quantity:  4

    - part_no:   E1628
      descrip:   High Heeled "Ruby" Slippers
      size:      8
      price:     133.7
      quantity:  1bill-to:  &id001
    street: | 
            123 Tornado Alley
            Suite 16
    city:   East Centerville
    state:  KSship-to:  *id001   

specialDelivery:  >
    Follow the Yellow Brick
    Road to the Emerald City.
    Pay no attention to the
    man behind the curtain....
注意在YAML中，字串不一定要用雙引號標示。另外，在縮排中空白字元的數目並不是非常重要，只要相同階層的元素左側對齊就可以了（不過不能使用TAB字元）。這個檔案的頂層由七個鍵值組成：其中一個鍵值"items"，是兩個元素構成的陣列（或稱清單），這清單中的兩個元素同時也是包含了四個鍵值的雜湊表。檔案中重複的部分用這個方法處理：使用錨點（&）和參照（*）標籤將"bill-to"雜湊表的內容複製到"ship-to"雜湊表。也可以在檔案中加入選擇性的空行，以增加可讀性。在一個檔案中，可同時包含多個檔案，並用"---"分隔。選擇性的符號"..."可以用來表示檔案結尾（在利用串流的通訊中，這非常有用，可以在不關閉串流的情況下，發送結束訊號）。

YAML的基本元件

YAML提供縮排／區塊以及內置（inline）兩種格式，來表示清單和雜湊表。以下展示幾種YAML的基本原件。

清單（陣列）

習慣上清單比較常用區塊格式（block format）表示，也就是用短槓+空白字元作為起始。
 --- # 最喜愛的電影
 - Casablanca
 - North by Northwest
 - Notorious
另外還有一種內置格式（inline format）可以選擇──用方括號圍住，並用逗號+空白區隔（類似JSON的語法）。
 --- # 購物清單 
 [milk, pumpkin pie, eggs, juice]

雜湊表

鍵值和資料由冒號及空白字元分開。區塊形式（常使用與YAML資料文件中）使用縮進和換行符分隔key: value對。內置形式（常使用與YAML資料串流中）在大括號中使用逗號+空白字元分隔key: value對。
 --- # 區塊形式
   name: John Smith
   age: 33 --- # 內置形式
 {name: John Smith, age: 33}

區塊的字元

再次強調，字串不需要包在引號之內。有兩種方法書寫多行文字（multi-line strings），一種可以儲存新行（使用|字元），另一種可以摺疊新行（使用>字元）。

儲存新行(Newlines preserved)

data: |                                     # 譯者注：這是一首著名的五行民謠(limerick)
   There once was a man from Darjeeling     # 這裡曾有一個人來自大吉嶺
   Who got on a bus bound for Ealing        # 他搭上一班往伊靈的公車
       It said on the door                  # 門上這麼說的
       "Please don't spit on the floor"     # "請勿在地上吐痰"
   So he carefully spat on the ceiling      # 所以他小心翼翼的吐在天花板上
根據設定，前方的引領空白符號（leading white space）必須排成條狀，以便和其他資料或是行為（如範例中的縮排）明顯區分。

摺疊新行(Newlines folded)

data: >
   Wrapped text         # 摺疊的文字
   will be folded       # 將會被收
   into a single        # 進單一一個
   paragraph            # 段落
   
   Blank lines denote   # 空白的行代表
   paragraph breaks     # 段落之間的區隔
和儲存新行不同的是，換行字元會被轉換成空白字元。而引領空白字元則會被自動消去。

於清單中使用雜湊表

- {name: John Smith, age: 33}- name: Mary Smith
  age: 27

於雜湊表中使用清單

men: [John Smith, Bill Jones]women:
  - Mary Smith
  - Susan Williams

YAML的進階元件

這部分算是一個後續的討論，在比較各種數資料列語言時，YAML最常被提到的特色有兩個：關係樹和資料形態。

資料合併和參考

為了維持檔案的簡潔，並避免資料輸入的錯誤，YAML提供了結點參考（*）和雜湊合併（<<）參考到其他結點標籤的錨點標記（&）。參考會將樹狀結構加入錨點標記的內容，並可以在所有資料結構中運作（可以參考上面"ship-to"的範例）合併只有雜湊表可以使用，可以將鍵值自錨點標記複製到指定的雜湊表中。
當資料被instantiate合併和參考會被剖析器自動展開。
#眼部雷射手術之標準程序---- step:  &id001                  # 定義錨點標籤 &id001
    instrument:      Lasik 2000
    pulseEnergy:     5.4
    pulseDuration:   12
    repetition:      1000
    spotSize:        1mm- step:
     <<: *id001                  # 合併鍵值：使用在錨點標籤定義的內容
     spotSize:       2mm         # 覆寫"spotSize"鍵值- step:
     <<: *id001                  # 合併鍵值：使用在錨點標籤定義的內容
     pulseEnergy:    500.0       # 覆寫鍵值
     alert: >                    # 加入其他鍵值
           warn patient of 
           audible pop

資料形態

由於自動判定資料形態的功能，嚴格型態（也就是使用者有宣告的資料形態）很難在大部分的YAML檔案中看到。資料型態可以被區分成三大類：原碼（core），定義（defined），使用者定義（user-defined）。原碼可以自動被解析器分析（例如：浮點數，整數，字串，清單，對映，...）。有一些進階的資料形態──例如位元資料──在YAML中有被「定義」，但不是每一種解析器都有支援。最後，YAML支援使用者自訂的區域變數，包括：自訂的類別，結構或基本型態（例如：四倍精度的浮點數）。

強迫轉型

YAML的自動判定資料形態是哪一種實體。但有時使用者會想要將資料強迫轉型成自訂的某種型態。最常見的狀況是字串，有時候可能看起來像數字或布林值，這種時候可以使用雙引號，或是使用嚴格型態標籤。
---a: 123                     # 整數b: "123"                   # 字串（使用雙括號）c: 123.0                   # 浮點數d: !!float 123             # 浮點數，使用!!表達的嚴格型態e: !!str 123               # 字串，使用嚴格型態f: !!str Yes               # 字串，使用嚴格型態g: Yes                     # 布林值"真"h: Yes we have No bananas  # 字串（包含"Yes"和"No"）

其他特殊資料形態

除了一般的資料形態之外，使用者也可以使用一些較為進階的型態，但不保證可被每種解析器分析。使用時和強迫轉型類似，要在形態名稱之前加上兩個驚嘆號（!!）。有幾種重要的形態在本篇沒有討論，包括集合（sets），有序映照（ordered maps），時間戳記（timestamps）以及十六進位資料（hexadecimal）。下面這個範例則是位元資料（binary）
---picture: !!binary |
 R0lGODlhDAAMAIQAAP//9/X
 17unp5WZmZgAAAOfn515eXv
 Pz7Y6OjuDg4J+fn5OTk6enp
 56enmleECcgggoBADs=mZmE

使用者自行擴充的資料形態

許多YAML的實現允許使用者自訂資料形態。在將一個物件序列化時，這個方法還頗方便的。某些區域資料形態可能不存在預設的資料形態中，不過這種型態在特定的YAML應用程式中是有定義的。這種區域資料形態用驚嘆號（ ! ）表示。 
---myObject:  !myClass { name: Joe, age: 15}

與其他資料序列化格式比較

雖然YAML是參考JSON，XML和SDL等語言，不過跟這些語言比起來，YAML仍有自己的特色。

JSON

JSON的語法是YAML1.2版的子集,，同時非常接近 YAML1.0與1.1版的子集，因此大部分的JSON檔案都可以被YAML的剖析器剖析。這是因為JSON的語法結構和YAML的內置格式相同。雖然大範圍的分層也可以使用類似JSON的內置格式，不過YAML標準並不建議這樣使用，除非這樣編寫能讓檔案可讀性增加。YAML的許多擴展在JSON是找不到的，如：進階資料形態、關係錨點、字串不需要雙引號、對映資料形態會儲存鍵值的順序。

XML和SDL

XML和SDL標籤概念，在YAML中是找不到的。對於資料結構序列（儘管這是有爭議的），標籤屬性的特色就是可以將資料及複雜資料附加資訊分離，並將各種原生資料結構（如：雜湊表、陣列）用同一種語言表示。YAML則以資料的可擴展性作為替代。（包括為了類比物件的類別型態）在YAML本身的規範中，並沒有類似XML的語言定義檔案剛要（language-defined document schema descriptors）──例如驗證自己本身的結構是否正確的檔案。不過，YAML綱要描述語言（YAML schema descriptor language）是存在的。另外還有YAXML──用XML描述YAML的結構──可以讓XML Schema與XSLT轉換程式應用在YAML之上。況且，在一般使用的情況下，YAML豐富的定義型態之語法已經提供了足夠的方式，來辨認YAML檔案是否正確。

縮排劃界

由於YAML的運作主要依賴大綱式的縮排來決定結構，這有效解決了界定符衝突（Delimiter collision）的問題。YAML的資料形態不依賴引號之特點，使的YAML檔案可以利用區塊，輕易的插入各種其他類型檔案，如：XML、SDL、JSON，甚至插入另一篇YAML。
---example: >
        HTML goes into YAML without modificationmessage: |

        <blockquote style="font: italic 12pt Times">
        <p>"Three is always greater than two,
           even for large values of two"</p>
        <p>--Author Unknown</p>
        </blockquote>
相反的，要將YAML置入XML或SDL中時，需要將所有空白字元和位勢符號（potential sigils，如：<,>和&）轉換成實體語法；要將YAML置入JSON中，需要用引號框住，並轉換內部的所有引號。

非階層式的資料模型

跟SDL、JSON等，每個子結點只能有單一一個父節點的階層是模型不同，YAML提供了一個簡單的關係體制，可以從樹狀結構的其他地方，重複相同的資料，而不必顯示那些冗餘的結構。這點和XML中的IDRef類似YAML剖析器在將YAML轉換成物件時，會自動將那些參考資料的結構展開，所以程式在使用時並不會查覺到哪些資料是解碼自這種結構。XML則不會將這種結構展開。這種表示法可以增加程式的可讀性，並且，在那種『大部分參數維持和上次相同，只有少數改變』的設定檔及通訊協定中，可以減少資料輸入錯誤。一個例子是：『送貨地點』和『購買地點』在發票的紀錄中幾乎都是相同的資料。

實際的考量

YAML是「行導向的」，因此，就算想由現有程式的混亂輸出，轉換成YAML格式，並保留大部分的原始檔案之外觀，也非常簡單。因為他不需要平衡封閉的標籤、括弧及引號，可以從很簡單的利用程式，從報表產生YAML。同樣，空格分隔可讓使用行導向的命令如：grep、Awk、perl、ruby，和Python，來應急性的過濾YAML檔案時更加方便。
特別是與標記語言不同的，連續的YAML區塊導嚮往往是格式良好的YAML檔案本身。這使得很容易撰寫那種「在開始提取的具體記錄之前，不需要'讀取全部檔案內容'」的解析器（通常需要平衡起始和關閉標籤、尋找引號和跳脫字元）。當處理一個單一靜態的，整個存在記憶體中的資料結構將很大，或為提取一個項目來重建的整個結構，代價相當昂貴的記錄檔，這種特性是相當方便的。
值得討論的是，儘管它的縮排方式似乎複雜化了深度很大的巢狀層次， YAML將縮排視為一個單一的空白，這可能會取得比其他標記語言更好的壓縮比。此外，極深的縮排可以完全避免的是： (1)使用「內置格式」（即簡稱類JSON格式）而無縮排；或 (2)使用關聯錨點展開階層以形成一個攤平的格式，使得YAML解析器能透明地重組成完整的資料結構。

安全性

YAML是純粹用來表達資料的語言，所以內部不會存程式碼注射的可執行命令。這代表剖析器會相當（至少）安全的解析檔案，而不用擔心潛在與執行命令相關的安全漏洞。舉例來說，JSON是JavaScript的子集，因此可能有人想使用JavaScript本身的剖析器直接eval，不過這樣一來就造成許多程式碼注射的漏洞。雖然在所有資料序列語言中，安全解析本質上是可能的，但可執行性卻正是這樣一個惡名昭彰的缺陷；而YAML缺乏相關的命令語言，可能是一個相對安全的利益。

資料處理和呈現

XML和YAML規範提供非常不同的邏輯模型來進行資料結點的展現、處理及儲存。

移植性

簡單的YAML檔案（例如：簡單的鍵值對）不需要完整的YAML剖析器，便可以被正規表示式解析。許多常用的程式語言──純用某個語言，讓函式庫具有可攜性──都有的YAML的產生器和剖析器。當效能比較重要時，也有許多和C語言綁定的函式庫可使用。