YAML:修订间差异

来自站长百科
跳转至: 导航、​ 搜索
无编辑摘要
无编辑摘要
 
第1行: 第1行:
[[Image:yaml.gif|right|200px|thumb|YAML [[Logo]]]]
[[Image:yaml.gif|right|200px|thumb|YAML [[Logo]]]]
'''YAML''',是一个可读性高,用来表达资料序列的编程语言。YAML参考了其他多种语言,包括:[[XML]]、[[C语言]]、[[Python]]、[[Perl]]以及[[电子邮件]]格式RFC2822。Clark Evans在[[2001年]]在首次发表了这种语言,另外Ingy döt Net与Oren Ben-Kiki也是这语言的共同设计者。目前已经有数种编程语言或脚本语言支援(或解析)这种语言。YAML是"YAML Ain't a Markup Language"(YAML不是一种置标语言)的递归缩写。在开发的这种语言时,YAML 的意思其实是:"Yet Another Markup Language"(仍是一种置标语言),但为了强调这种语言以数据做为中心,而不是以置标语言为重点,而用返璞词重新命名。
'''YAML''',是一个可读性高,用来表达资料序列的编程语言。YAML参考了其他多种语言,包括:[[XML]]、[[C语言]]、[[Python]]、[[Perl]]以及[[电子邮件]]格式。Clark Evans在[[2001年]]在首次发表了这种语言,另外Ingy döt Net与Oren Ben-Kiki也是这语言的共同设计者。目前已经有数种编程语言或脚本语言支援(或解析)这种语言。YAML是"YAML Ain't a Markup Language"(YAML不是一种置标语言)的递归缩写。在开发的这种语言时,YAML 的意思其实是:"Yet Another Markup Language"(仍是一种置标语言),但为了强调这种语言以数据做为中心,而不是以置标语言为重点,而用返璞词重新命名。


== YAML的功能 ==
== YAML的功能 ==
第13行: 第13行:
date:        2007-08-06
date:        2007-08-06
customer:
customer:
    given:  Dorothy
given:  Dorothy
    family:  Gale
family:  Gale
    
    
items:
items:
    - part_no:  A4786
- part_no:  A4786
      descrip:  Water Bucket (Filled)
descrip:  Water Bucket (Filled)
      price:    1.47
price:    1.47
      quantity:  4
quantity:  4


    - part_no:  E1628
- part_no:  E1628
      descrip:  High Heeled "Ruby" Slippers  
descrip:  High Heeled "Ruby" Slippers  
      price:    100.27
price:    100.27
      quantity:  1
quantity:  1


bill-to:  &id001
bill-to:  &id001
    street: |  
street: |  
            123 Tornado Alley
      123 Tornado Alley
            Suite 16
      Suite 16
    city:  East Westville
city:  East Westville
    state:  KS
state:  KS


ship-to:  *id001   
ship-to:  *id001   


specialDelivery:  >
specialDelivery:  >
    Follow the Yellow Brick
Follow the Yellow Brick
    Road to the Emerald City.
Road to the Emerald City.
    Pay no attention to the  
Pay no attention to the  
    man behind the curtain.
man behind the curtain.
...
...
</pre>
</pre>
注意在YAML中,字符串不一定要用双引号标示。另外,在缩排中空白字符的数目并不是非常重要,只要相同阶层的元素左侧对齐就可以了(不过不能使用TAB字符)。这个文件的的顶层由七个键值组成:其中一个键值"items",是个两个元素构成的阵列(或称清单),这清单中的两个元素同时也是包含了四个键值的杂凑表。文件中重复的部分用这个方法处理:使用锚点(&)和参考(*)标签将"bill-to"杂凑表的内容复制到"ship-to"杂凑表。也可以在文件中加入选择性的空行,以增加可读性。在一个档案中,可同时包含多个文件,并用"——"分隔。选择性的符号"..."可以用来表示档案结尾(在利用串流的通讯中,这非常有用,可以在不关闭串流的情况下,发送结束讯号)。
注意在YAML中,[[字符串]]不一定要用双引号标示。另外,在缩排中空白字符的数目并不是非常重要,只要相同阶层的元素左侧对齐就可以了(不过不能使用TAB字符)。这个文件的的顶层由七个键值组成:其中一个键值"items",是个两个元素构成的阵列(或称清单),这清单中的两个元素同时也是包含了四个键值的杂凑表。文件中重复的部分用这个方法处理:使用锚点(&)和参考(*)标签将"bill-to"杂凑表的内容复制到"ship-to"杂凑表。也可以在文件中加入选择性的空行,以增加可读性。在一个档案中,可同时包含多个文件,并用"——"分隔。选择性的符号"..."可以用来表示档案结尾(在利用串流的通讯中,这非常有用,可以在不关闭串流的情况下,发送结束讯号)。


== YAML语言的构成元素 ==
== YAML语言的构成元素 ==
第88行: 第88行:
Who got on a bus bound for Ealing         
Who got on a bus bound for Ealing         
#他搭上一班往伊靈的公車
#他搭上一班往伊靈的公車
It said on the door                 
It said on the door                 
#門上這麼說的
#門上這麼說的
"Please don't spit on the floor"     
"Please don't spit on the floor"     
#"請勿在地上吐痰"
#"請勿在地上吐痰"
So he carefully spat on the ceiling     
So he carefully spat on the ceiling     
#所以他小心翼翼的吐在天花板上
#所以他小心翼翼的吐在天花板上
</pre>
</pre>
根据设定,前方的引领空白符号(leading white space)必须排成条状,以便和其他资料或是行为(如范例中的缩排)明显区分。
根据设定,前方的引领空白符号(leading white space)必须排成条状,以便和其他资料或是行为(如范例中的缩排)明显区分。
第244行: 第244行:
         <font name='times' size=10>
         <font name='times' size=10>
         <p><i>"Three is always greater than
         <p><i>"Three is always greater than
                two, even for large values of two"</i>
        two, even for large values of two"</i>
          </p><p>    --Author Unknown    </p></font>
        </p><p>    --Author Unknown    </p></font>
date: 2007-06-01
date: 2007-06-01
</pre>
</pre>

2011年5月26日 (四) 12:00的最新版本

YAML Logo

YAML,是一个可读性高,用来表达资料序列的编程语言。YAML参考了其他多种语言,包括:XMLC语言PythonPerl以及电子邮件格式。Clark Evans在2001年在首次发表了这种语言,另外Ingy döt Net与Oren Ben-Kiki也是这语言的共同设计者。目前已经有数种编程语言或脚本语言支援(或解析)这种语言。YAML是"YAML Ain't a Markup Language"(YAML不是一种置标语言)的递归缩写。在开发的这种语言时,YAML 的意思其实是:"Yet Another Markup Language"(仍是一种置标语言),但为了强调这种语言以数据做为中心,而不是以置标语言为重点,而用返璞词重新命名。

YAML的功能[ ]

YAML的语法和其他高阶语言类似,并且可以简单表达清单、杂凑表,标量等资料形态。它使用空白符号缩排和大量依赖外观的特色,特别适合用来表达或编辑数据结构、各种设定档、倾印除错内容、文件大纲(例如:许多电子邮件标题格式和YAML非常接近)。尽管它比较适合用来表达阶层式(hierarchical model)的数据结构,不过也有精致的语法可以表示关联性(relational model)的资料。由于YAML使用空白字符和分行来分隔资料,使的他特别适合用grep/Python/Perl/Ruby操作。其让人最容易上手的特色是巧妙避开各种封闭符号,如:引号、各种括号等,这些符号在巢状结构时会变得复杂而难以辨认。

YAML范例[ ]

数据结构可以用类似大纲的缩排方式呈现

---
receipt:     Oz-Ware Purchase Invoice
date:        2007-08-06
customer:
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 
price:     100.27
quantity:  1

bill-to:  &id001
street: | 
       123 Tornado Alley
       Suite 16
city:   East Westville
state:  KS

ship-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的基本元件

YAML提供缩排/区块以及内置(inline)两种格式,来表示清单和杂凑表。以下展示几种YAML的基本原件。

  • 清单(阵列)

习惯上清单比较常用区块格式(block format)表示,也就是用短杠+空白字符作为起始。

--- # 最喜愛的電影
- Casablanca
- North by Northwest
- Notorious

另外还有一种内置格式(inline format)可以选择──用方括号围住,并用逗号+空白区隔(类似JSON的语法)

--- # 购物清单 [milk, pumpkin pie, eggs, juice]

  • 杂凑表

键值和资料由冒号及空白字符分开。

--- # 区块形式
name: John Smith
age: 33
--- # 內置形式
{name: John Smith, age: 33}
  • 区块的字符

再次强调,字串不需要包在引号之内。保存新行(Newlines preserved)

--- |                                      
#译者注:這是一首著名的五行民谣(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)
--- >
  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语法[ ]

  • 在yaml.org(英文)可以找到轻巧而好用的小抄(亦是用YAML表示)及格式说明。下面的内容,是关于基本元件的摘要。
  • YAML使用可打印的Unicode字符,可使用UTF-8UTF-16
  • 使用空白字符为文件缩排来表示结构;不过不能使用跳格字符(TAB)。
  • 注解由井字号( # )开始,可以出现在一行中的任何位置,而且范围只有一行(也就是一般所谓的单行注解)
  • 每个清单成员以单行表示,并用短杠+空白( - )起始。或使用方括号( [ ] ),并用逗号+空白( , )分开成员。
  • 每个杂凑表的成员用冒号+空白( : )分开键值和内容。或使用大括号( { } ),并用逗号+空白( , )分开。
  • 杂凑表的键值可以用问号 ( ? )起始,用来明确的表示多个词汇组成的键值。
  • 字串平常并不使用引号,但必要的时候可以用双引号 ( " )或单引号 ( ' )框住。
  • 使用双引号表示字串时,可用倒斜线( \ )开始的跳脱字符(这跟C语言类似)表示特殊字符。
  • 区块的字串用缩排和修饰词(非必要)来和其他资料分隔,有新行保留(preserve)(使用符号 | )或新行折叠(flod)(使用符号 > )两种方式。
  • 在单一档案中,可用连续三个连字号(——)区分多个档案。
  • 另外,还有选择性的连续三个点号( ... )用来表示档案结尾。
  • 重复的内容可使从参考标记星号 ( * )复制到锚点标记( & )。
  • 指定格式可以使用两个惊叹号 ( !! ),后面接上名称。
  • 档案中的单一文件可以使用指导指令,使用方法是百分比符号( % )。有两个指导指令在YAML1.1版中被定义:
  • %YAML 指导指令,用来识别文件的YAML版本。
  • %TAG 指导指令,被用在URI的字首标记。这个方法在标记节点的型态时相当有用。
  • YAML再使用逗号及冒号时,后面都必须接一个空白字符,所以可以再字串或数值中自由加入分隔符号(例如:5,280或http://www.wikipedia.org)而不需要使用引号。
  • 另外还有两个特殊符号在YAML中被保留,有可能在未来的版本被使用--( @ )和( ` )。

与其他资料序列语言比较[ ]

  • JSON

JSON的语法是YAML1.2版的子集[5],,同时非常接近[6] 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 modification
message:  |
        <font name='times' size=10>
         <p><i>"Three is always greater than
         two, even for large values of two"</i>
         </p><p>    --Author Unknown    </p></font>
date: 2007-06-01

相反的,要将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本身的剖析器是相当诱人的,不过也造成许多代码注射的漏洞。虽然在所有资料序列语言中,安全解析本质上是可能的,但可执行性却正是这样一个恶名昭彰的缺陷;而YAML缺乏相关的命令语言,可能是一个相对安全的利益。

  • 资料处理和呈现

XML和YAML规范提供非常不同的逻辑模型来进行资料结点的展现、处理及储存。

相关条目[ ]

参考来源[ ]