YAML是“另一种标记语言”的外语缩写。但为了强调这种语言以数据做为中心,而不是以置标语言为重点,而用返璞词重新命名。它是一种直观的能够被电脑识别的数据序列化格式,是一个可读性高并且容易被人类阅读,容易和脚本语言交互,用来表达资料序列的编程语言。 它是类似于标准通用标记语言的子集XML的数据描述语言,语法比XML简单很多。 =介绍= ==诞生== YAML参考了其他多种语言,包括:XML、C语言、Python、Perl以及电子邮件格式RFC2822。 Clark Evans在2001年5月在首次发表了这种语言,另外Ingy döt Net与Oren Ben-Kiki也是这语言的共同设计者。 ==命名== YAML是"YAML Ain't a Markup Language"(YAML不是一种置标语言)的递归缩写。 在开发的这种语言时,YAML 的意思其实是:"Yet Another Markup Language"(仍是一种置标语言), ==功能== YAML的语法和其他高阶语言类似,并且可以简单表达清单、散列表,标量等资料形态、。 它使用空白符号缩排和大量依赖外观的特色,特别适合用来表达或编辑数据结构、各种设定档、倾印除错内容、文件大纲(例如:许多电子邮件标题格式和YAML非常接近)。 尽管它比较适合用来表达阶层式(hierarchical model)的数据结构,不过也有精致的语法可以表示关联性(relational model)的资料。 由于YAML使用空白字符和分行来分隔资料,使的他特别适合用grep、Python、Perl、Ruby操作。 其让人最容易上手的特色是巧妙避开各种封闭符号,如:引号、各种括号等,这些符号在嵌套结构中会变得复杂而难以辨认。 =格式= ==多行缩进== 数据结构可以用类似大纲的缩排方式呈现,结构通过缩进来表示,连续的项目通过减号“-”来表示,map结构里面的key/value对用冒号“:”来分隔。样例如下: 1 house: 2 family: 3 name: Doe 4 parents: 5 - John 6 - Jane 7 children: 8 - Paul 9 - Mark 10 - Simone 11 address: 12 number: 34 13 street: Main Street 14 city: Nowheretown 15 zipcode: 12345 注意: 字串不一定要用双引号标识; 在缩排中空白字符的数目并不是非常重要,只要相同阶层的元素左侧对齐就可以了(不过不能使用TAB字符); 允许在文件中加入选择性的空行,以增加可读性; 在一个档案中,可同时包含多个文件,并用“——”分隔; 选择性的符号“...”可以用来表示档案结尾(在利用串流的通讯中,这非常有用,可以在不关闭串流的情况下,发送结束讯号)。 单行缩写 YAML也有用来描述好几行相同结构的数据的缩写语法,数组用'[]'包括起来,hash用'{}'来包括。因此,上面的这个YAML能够缩写成这样: 1 house: 2 family: { name: Doe, parents: [John, Jane], children: [Paul, Mark, Simone] } 3 address: { number: 34, street: Main Street, city: Nowheretown, zipcode: 12345 } =适用场景= ==脚本语言== 由于实现简单,解析成本很低,YAML特别适合在脚本语言中使用。列一下现有的语言实现:Ruby,Java,Perl,Python,PHP,OCaml,JavaScript,除了Java,其他都是脚本语言。 ==序列化== YAML比较适合做序列化。因为它是宿主语言数据类型直转的。 ==配置文件== YAML做配置文件也不错。写YAML要比写XML快得多(无需关注标签或引号),并且比ini文档功能更强。 比如Ruby on Rails的配置就选用的YAML。对ROR而言,这很自然,也很省事. 由于兼容性问题,不同语言间的数据流转建议不要用YAML. =语言比较= 虽然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。 相反的,要将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将缩排视为一个单一的空白,这可能会取得比其他标记语言更好的压缩比。此外,极深的缩排可以完全避免的是: 使用“内置格式”(即简称类JSON格式)而无缩排; 使用关联锚点展开阶层以形成一个摊平的格式,使得YAML解析器能透明地重组成完整的数据结构。 ==安全性== YAML是纯粹用来表达资料的语言,所以内部不会存代码注入的可执行命令。这代表剖析器会相当(至少)安全的解析文件,而不用担心潜在与执行命令相关的安全漏洞。举例来说,JSON是JavaScript的子集,使用JavaScript本身的剖析器是相当诱人的,不过也造成许多代码注入的漏洞。虽然在所有资料序列语言中,安全解析本质上是可能的,但可执行性却正是这样一个恶名昭彰的缺陷;而YAML缺乏相关的命令语言,可能相对安全。 ==资料处理和呈现== XML和YAML规范提供非常不同的逻辑模型来进行资料结点的展现、处理及储存。 =函式库= ==移植性== 简单的YAML档案(例如:简单的键值对)不需要完整的YAML剖析器,便可以被RegEx解析。许多常用的编程语言──纯用某个语言,让函式库具有可携性──都有的YAML的产生器和剖析器。当效能比较重要时,也有许多和C语言绑定的函式库可使用。 ==C语言== libYAML 2007-06时,这个YAML的函式库渐趋稳定,并被YAML格式作者推荐使用。 SYCK 这个实现支持大部分1.0版的格式,并且被广泛的使用。它使用高阶interpreted languages进行最佳化。在2005之后,这个专案已经不再更新,不过仍可使用。 ==Perl== YAML:: 一个通用的接口,被数个YAML剖析器使用。 YAML::Tiny YAML简化版的实现。拥有小巧轻快的优点──比完整功能的YAML实现快上许多──并用纯Perl写成。 YAML::Syck 与SYCK函式库绑定。提供快速,highly featured的YAML剖析器。 YAML::XS 与LibYaml绑定。提供1.1版更好的相容性。 ==PHP== Spyc 纯PHP的实现。 PHP-Syck 与SYCK函式库绑定。 sfYaml 为symfony项目重写的Spyc, 可独立使用, 可以产生和剖析YAML文件。 ==Python== PyYaml 纯Python,或可选用LibYAML的函式库。 PySyck 与SYCK绑定。 ==Ruby== 从1.8版开始,YAML剖析器成为标准函式库之一。以SYCK为基础。 Ya2YAML with full UTF-8 support ==Java== jvyaml 以Syck为基础,and patterned off ruby-yaml JYaml 纯Java的实现。 ==R== CRAN YAML 以SYCK为基础。 ==JavaScript== 原生的JavaScript即可产生YAML,但不能剖析。 YAML JavaScript 产生和剖析。 ==.NET== 待补充。 ==OCaml== OCaml-Syck ==C++== 用C++将libYaml包装。 ==Objective-C== Cocoa-Syck ==Lua== Lua-Syck ==Haskell=== Haskell Reference wrappers ==XML== YAXML currently draft only。 |