Yaml学习笔录
YAML概要
[YAML](http://yaml.org/)是"YAML Ain't a Markup Language"(YAML不是一种置标语言)的递归缩写,早先YAML的意思其实是:"Yet Another Markup Language"(另外一种置标语言),但为了强调这种语言以数据做为中心,而不是以置标语言为重点,而用返璞词重新命名,YAML的官方定义很简单,即**一种人性化的数据格式定义语言**,其主要功能用途类似于XML或JSON,YAML使用空白字符和分行来分隔数据,且巧妙避开各种封闭符号,如:引号、括号等,以避免这些符号在复杂层次结构中变得难以辨认。YAML的语法与高阶语言类似,可以很简单地表述*序列(java中的list)、杂凑表(java中的map)、标量(java中的基本类型等)*数据结构,它重点强调可阅读性。
YAML vs XML
与YAML相似的数据格式定义语言是XML,YAML比XML优越性表现在:
- YAML的可读性好
- YAML和脚本语言的交互性好
- YAML使用实现语言的数据类型
- YAML有一个一致的信息模型
- YAML易于实现
上面5条是XML不足的地方,同时,YAML也具有XML的下列优点:
- YAML可以基于流来处理
- YAML表达能力强,扩展性好
YAML类似于XML的数据描述语言,语法比XML简单很多,YAML试图用一种比XML更敏捷的方式,来完成XML所完成的任务。
YAML vs JSON
JSON的语法其实是YAML的子集,大部分的JSON文件都可以被YAML的剖析器剖析。虽然大部分的数据分层形式也可以使用类似JSON的格式,不过YAML并不建议这样使用,除非这样编写能让文件可读性增加,更重要的是,YAML的许多扩展在JSON是找不到的,如:*进阶资料形态*、*关系锚点*、*字串不需要引号*、*映射资料形态会储存键值的顺序*等。
YAML用途
1、脚本语言
由于实现简单,解析成本很低,YAML特别适合在脚本语言中使用。列一下现有的语言实现:Ruby,Java,Perl,Python,PHP,OCaml,JavaScript,除了Java,其他都是脚本语言。
2、序列化
YAML比较适合做序列化。因为它是宿主语言数据类型直转的。
3、配置文件
YAML做配置文件也不错。写YAML要比写XML快得多(**无需关注标签或引号**),并且比ini文档功能更强。
4、调试
由于其很强的阅读性,用于调试过程中dump出信息供分析也是一种比较方便的做法。
YAML缺陷与不足
YAML没有自己的数据类型的定义,而是使用实现语言的数据类型。一个YAML文件,在不同语言中解析后得到的数据类型可能会不同,由于其兼容性问题,不同语言间的数据流转不建议使用YAML。
YAML语法与范例
- YAML使用可打印的Unicode字符,可使用UTF-8或UTF-16
- 使用**空白字符**(不能使用<kbd>Tab</kbd>)分层,同层元素左侧对齐
- 单行注解由井字号(<kbd> #</kbd> )开始,可以出现在行中任何位置
- 每个清单成员以单行表示,并用短杠+空白(<kbd>- </kbd>)起始
- 每个杂凑表的成员用冒号+空白(<kbd>: </kbd>)分开键和值
- 杂凑表的键值可以用问号 (<kbd>?</kbd>)起始,表示多个词汇组成的键值
- 字串一般不使用引号,但必要的时候可以用引号框住
- 使用双引号表示字串时,可用倒斜线(<kbd>\</kbd>)进行特殊字符转义
- 区块的字串用缩排和修饰词(非必要)来和其他资料分隔,有新行保留(使用符号<kbd>|</kbd>)或新行折叠(使用符号<kbd>></kbd>)两种方式
- 在单一档案中,可用连续三个连字号(<kbd>---</kbd>)区分多个档案
- 可选择性的连续三个点号(<kbd>...</kbd>)用来表示档案结尾(在流式传输时非常有用,不需要关闭流即可知道到达结尾处)
- 重复的内容可使从参考标记星号 (<kbd>*</kbd>)复制到锚点标记(<kbd>&</kbd>)
- 指定格式可以使用两个惊叹号 ( !! ),后面接上名称。
- 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.
这个文件的的顶层由七个键值组成:其中一个键值"items",是个两个元素构成的清单,清单中的两个元素同时也是包含了四个键值的杂凑表。
文件中重复的部分处理方式:使用锚点(&)和参考(*)标签将"bill-to"杂凑表的内容复制到"ship-to"杂凑表。也可以在文件中加入选择性的空行,以增加可读性。
YAML的JAVA实现
YAML已经有了多种语言不少实现,详见[YAML官网](http://yaml.org/)。
一般YAML文件扩展名为.yaml,比如John.yaml,其内容为:
- name: John Smith
- age: 37
- children:
- - name: Jimmy Smith
- age: 15
- - name: Jenny Smith
- age: 12
- spouse:
- name: Jane Smith
- age: 25
对John.yaml进行java描述,抽象出一个Person类,如下:
- public class Person {
- private String name;
- private int age;
- private Person sponse;
- private Person[] children;
- // setXXX, getXXX方法略.
- }
现在我们使用java装配一个Jone:
- Person john = new Person();
- john.setAge(37);
- john.setName("John Smith");
- Person sponse = new Person();
- sponse.setName("Jane Smith");
- sponse.setAge(25);
- john.setSponse(sponse);
- Person[] children = {new Person(), new Person()};
- children[0].setName("Jimmy Smith");
- children[0].setAge(15);
- children[1].setName("Jenny Smith");
- children[1].setAge(12);
- john.setChildren(children);
使用SnakeYAML实现
项目主页:http://code.google.com/p/snakeyaml/
使用手册:https://code.google.com/p/snakeyaml/wiki/Documentation
SnakeYAML是一个标准的YAML的java实现,它有以下特点:
- 完全支持YAML 1.1,可以跑通规范中的所有示例
- 支持YAML的所有类型
- 支持UTF-8/UTF-16的输入和输出
- 提供了本地java对象的序列化和反序列化的高层API
- 提供相对合理的错误提示信息
使用SnakeYAML将john dump出来,**如果有引用相同对象,则dump出到yaml文件会自动使用<kbd>&</kbd>和<kbd>*</kbd>进行锚点和引用**:
- DumperOptions options = new DumperOptions();
- options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
- Yaml yaml = new Yaml(options);
- //Yaml yaml = new Yaml();
- String dump = yaml.dump(john);
- System.out.println(dump);
内容如下:
- !!Person
- age: 37
- children:
- - age: 15
- children: null
- name: Jimmy Smith
- sponse: null
- - age: 12
- children: null
- name: Jenny Smith
- sponse: null
- name: John Smith
- sponse:
- age: 25
- children: null
- name: Jane Smith
- sponse: null
现在用SnakeYAML把yaml load进来,**如果yaml文件中使用了<kbd>&</kbd>和<kbd>*</kbd>,则会自动对load出来的对象赋相同的值**:
- Yaml yaml = new Yaml();
- Object load = yaml.load(new FileInputStream(new File("jhon.yaml")));
- System.out.println(load.getClass());
- System.out.println(yaml.dump(load));
或
- Yaml yaml = new Yaml(options);
- Person person = yaml.loadAs(inputStream, Person.class);
- System.out.println(person.getSponse().getChildren().length);
如果一个yaml文件中有多个文档,由<kbd>---</kbd>分割,解析如下:
- Yaml yaml = new Yaml();
- int counter = 0;
- for (Object data : yaml.loadAll(input)) {
- System.out.println(data);
- counter++;
- }
保存一个Map对象:
- Map<String, Object> data = new HashMap<String, Object>();
- data.put("name", "Silenthand Olleander");
- data.put("race", "Human");
- data.put("traits", new String[] { "ONE_HAND", "ONE_EYE" });
- Yaml yaml = new Yaml();
- String output = yaml.dump(data);
- System.out.println(output);
- // or
- StringWriter writer = new StringWriter();
- yaml.dump(data, writer);
- System.out.println(writer.toString());
将多个文档dump出到同一个yaml文件中去:
- List<Integer> docs = new LinkedList<Integer>();
- for (int i = 1; i < 4; i++) {
- docs.add(i);
- }
- DumperOptions options = new DumperOptions();
- //options.setCanonical(true);
- options.explicitStart(true);
- Yaml yaml = new Yaml(options);
- System.out.println(yaml.dump(docs));
- System.out.println(yaml.dumpAll(docs.iterator()));
- --- [1, 2, 3]
- --- 1
--- 2
--- 3
YAML与java类型对照表:
- YAML | JAVA
- -------- | -------
- !null |null
- !!bool |Boolean
- !!int |Integer, Long, BigInteger
- !!float |Double
- !!binary |String
- !!timestamp |java.util.Date, java.sql.Date, java.sql.Timestamp
- !!omap, !!pairs |List of Object[]
- !!set |Set
- !!str |String
- !!seq |List
- !!map |Map
集合的默认实现是:
- List: ArrayList
- Map: LinkedHashMap
使用JYaml实现
JYaml(**最新版本是2007年的,可以考虑放弃了**),使用JYaml把Jone “Dump” 出来:
- File dumpfile = new File("John_dump.yaml");
- Yaml.dump(john, dumpfile);
下面我们看看John_dump.yaml是什么样子:
- --- !yaml.test.internal.Person
- age: 37
- children: !yaml.test.internal.Person[]
- - !yaml.test.internal.Person
- age: 15
- name: Jimmy Smith
- - !yaml.test.internal.Person
- age: 12
- name: Jenny Smith
- name: John Smith
- sponse: !yaml.test.internal.Person
- age: 25
- name: Jane Smith
其中!yaml.test.internal.Person是一些类型的信息。load的时候需要用。
现在用JYaml把Jone_dump.yaml load进来:
- Person john2 = (Person) Yaml.loadType(dumpfile, Person.class);
还可以用下面的代码dump出没有类型信息的John.yaml:
- Yaml.dump(john,dumpfile, true);
我们再来看看JYaml对流处理的支持,为简便起见,我们只是把同一个john写10次:
- YamlEncoder enc = new YamlEncoder(new FileOutputStream(dumpfile));
- for(int i=0; i<10; i++){
- john.setAge(37+i);
- enc.writeObject(john);
- enc.flush();
- }
- enc.close();
下面再把这十个对象一个一个读出来(注意while循环退出的方式):
- YamlDecoder dec = new YamlDecoder(new FileInputStream(dumpfile));
- int age = 37;
- while(true){
- try{
- john = (Person) dec.readObject();
- assertEquals(age, john.getAge());
- age++;
- }catch(EOFException eofe){
- break;
- }
- }
Yaml学习笔录的更多相关文章
- YAML学习
YAML学习 一:什么是YAML?YAML是专门用来写配置文件的语言,通过它来编写完成后,我们可以通过插件JS-YAML(https://github.com/nodeca/js-yaml)来转换成我 ...
- 【Yaml】Yaml学习笔记
转载:https://blog.csdn.net/moshenglv/article/details/52084899 YAML何许物也?在XML泛滥的情况下,YAML的出现的确让人眼前一亮,在初步学 ...
- 更适合Pythoner的标记语言Yaml学习总结
pythonic的标记语言 之前总结过一篇关于小数据存储文件大比拼,当时着重介绍了json,因为它在各类编程语言的通用性较强.但今天,我想给大家介绍一款更加适合pythoner使用的语言Yaml. Y ...
- ADO.NET Entity Framework学习笔录(一)
今天开始学习了EF的相关内容,以前只知道ADO.NET,今天学习后觉得有必要写个相关的学习心得,今天就先写第一篇. 我们的再学习的过程中所用到的环境是Windows7+SQLServer2008+VS ...
- 性能测试LR学习笔录 -2
LoadRunner基本测试流程: 制定性能测试计划(部分) -> 创建测试脚本 -> 编译.运行测试脚本 -> 创建场景 - > 运行.监控场景.收集数据 -> 生 ...
- Python Yaml 学习
最近开始使用Python3.x,所有今后无特殊说明,Python代表的就是Python3.x 最近在看代码时发现有人用Yaml —— Yet Another Markup Language :另一种标 ...
- Yaml学习文档
pdf文档地址 http://yaml.org/spec/ JS-Yaml demo地址 http://nodeca.github.io/js-yaml/
- SVG学习笔录(一)
SVG可缩放矢量图形(Scalable Vector Graphics)这项技术,现在越来越让大家熟知,在h5的移动端应用使用也越来越广泛了, 下面让我分享给大家svg学习的经验. HTML体系中,最 ...
- DDD学习笔录——提炼问题域之知识提炼与协作的基本原则
1.通过通用语言达成共识 通用语言,已经强调过好多遍了,在DDD再怎么重视都不为过,后面可能还会讲. 知识提炼的输出以及共识的构建就是常见的通用语言(UL). 当与业务相关人员和主题专家进行建模时,每 ...
随机推荐
- jmeter返回报文乱码问题
返回的报文中存在乱码如下: 1.先改脚本里面的 content encoding为utf-8 然后response为utf-8 如果以上还是不可以,那就改配置文件jmeter.properties,里 ...
- Java8安装配置
方法1.命令行安装 -jdk 存在多个版本,自动配置: sudo update-alternatives --config java 方法2.下载安装 下载java8的jdk http://www.o ...
- IOS开发 CocoaPods 使用 pod Install 出现 Updating local specs repositories
pod install 换成pod install --verbose --no-repo-update这个命令,前面的命令被墙了
- openssl指定证书密码建立连接
下面是server 和client 的代码.用没跑过,但是用类似的代码跑了.流程是这样的.要注意的是openssl中ssl连接建立前用阻塞的socket,建立后可以设置非阻塞.openssl每个操作后 ...
- 启动和连接MySQL服务
1.服务端启动 1.查看MySQL状态 sudo /etc/init.d/mysql status sudo /etc/init.d/mysql start | stop | restart sudo ...
- HihoCoder 1063 : 缩地 树形DP第二题(对象 边)
时间限制:12000ms 单点时限:1000ms 内存限制:256MB 描述 编织者是 Dota 系列中的一个伪核,拥有很强的生存能力和线上消耗能力.编织者的代表性技能是缩地.缩地带来的隐身.极限移动 ...
- LOJ2359. 「NOIP2016」天天爱跑步【树上差分】
LINK 思路 首先发现如果对于一个节点,假设一个节点需要统计从字数内来的贡献 需要满足\(dep_u - dep_s = w_u\) 这个条件其实可以转化成\(dep_u - w_u = dep_s ...
- BZOJ2820 YY的GCD 【莫比乌斯反演】
BZOJ2820 YY的GCD Description 神犇YY虐完数论后给傻×kAc出了一题给定N, M,求1<=x<=N, 1<=y<=M且gcd(x, y)为质数的(x, ...
- hadoop入门手册5:Hadoop【2.7.1】初级入门之命令:文件系统shell2
问题导读 1.改变hdfs文件的权限,需要修改哪个配置文件?2.获取一个文件的或则目录的权限,哪个命令可以实现?3.哪个命令可以实现设置访问控制列表(ACL)的文件和目录? 接上篇:Hadoop[2. ...
- altera官方推荐时钟使用方法
Register Combinational Logic Outputs If you use the output from combinational logic as a clock signa ...