YAML

Yaml是一种“是一个可读性高并且容易被人类阅读,容易和脚本语言交互,用来表达资料序列的编程语言。”类似于XML但比XML更简洁,语法详见
http://www.ruanyifeng.com/blog/2016/07/yaml.html
在JAVA中也有相关的类库可以进行解析YAML

准备工作

这里使用gradle加入依赖

compile 'org.yaml:snakeyaml:1.17'

之后就可以使用了

load

先上代码

	@Test
	public void load() throws FileNotFoundException{
		//初始化Yaml解析器
		Yaml yaml = new Yaml();
		File f=new File("test.yaml");
		//读入文件
		Object result= yaml.load(new FileInputStream(f));
		System.out.println(result.getClass());
		System.out.println( result);
	}
----test.yaml---
a: 1
b: 2
----输出---
class java.util.LinkedHashMap
{a=1, b=2}

这里load方法支持String,InputStream,Reader作为输入

loadall

在一个yaml文件中可以存入多组配置并使用loadAll进行读取,多组之间使用三个横杠分开

	@Test
	public void loadall() throws FileNotFoundException {
		Yaml yaml = new Yaml();
		File f = new File("test.yaml");
		Iterable<Object> result = yaml.loadAll(new FileInputStream(f));
		for (Object obj : result) {
			System.out.println(obj.getClass());
			System.out.println(obj);
		}
	}
----test.yaml---
a: 1
b: 2
---
c: 3
----输出---
class java.util.LinkedHashMap
{a=1, b=2}
class java.util.LinkedHashMap
{c=3}

这里返回的是一个Iterable,每个对象的解析是在遍历到的时候进行的是懒加载的

java对象

snakeyaml还支持普通java类型的读取

	@Test
	public void loadPojo() throws FileNotFoundException {
		Yaml yaml = new Yaml();
		File f = new File("test.yaml");
		Map result= (Map) yaml.load(new FileInputStream(f));
		System.out.println(result);
		System.out.println(result.get("pojo"));
		System.out.println(result.get("pojo2"));
	}
public class Pojo {
	public String name;
	public Pojo(String name){
		this.name=name
	}
	@Override
	public String toString(){
		return "name->"+name;
	}
}
----test.yaml---
pojo: !!yaml.Pojo {name: name}
pojo2: !!yaml.Pojo [ name]

这里简单定义了一个pojo然后在配置文件中有两种方式第一种(使用大括号{})是通过变量名进行赋值,第二种(使用方括号[])是通过构造方法进行赋值

dump

同时还支持将对象反向编译成yaml配置

	@Test
	public void dump() throws FileNotFoundException {
		Yaml yaml = new Yaml();
		Pojo p=new Pojo();
		p.name="name";
		System.out.println( yaml.dump(p));
	}
----输出---
!!yaml.Pojo {name: name}

Yaml配置

上面使用的都是YAML的无参构造方法,其实YAML在构造方法中还有可以配置参数
主要有如下4个

constructor

用于配置构造对象的创建过程

representer

用于配置yaml文件中对应tag响应解析成的对象
Representer representer = new Representer();
representer.addClassTag(Car.class, new Tag("!car"));//这里!car就会使用Car类型来解析,而不需要再配置文件中写全car的包名
representer.addClassTag(Wheel.class, Tag.MAP);//会使用Wheel对map的类型进行解析

dumpoption

这个是在dump时,控制输出的宽度,对齐,类类型等相关信息

resolver

用于隐式识别对应类型,只要符合了对应的pattern就会使用对应的tag进行解析
yaml.addImplicitResolver(new Tag("!dice"), Pattern.compile("\d+d\d+"), "123456789");

alias merge

yaml支持别名引用(&用于起别名 *用于引用),以及merger(<<:)

- &anchor
  boolean: true
  integer: 3
- <<: *anchor
  integer: 7
----输出---
[{boolean=true, integer=3}, {integer=7, boolean=true}]

可以看到第二个map自动merge了应用的boolean而integer覆盖了原来的值3

备注

参考官方文档:https://bitbucket.org/asomov/snakeyaml/wiki/Documentation