超越XML和JSON:YAML

时间:2023-01-15 07:53:56
为Java开发者对YAML文件格式做一个高级介绍,找出它与XML和JSON的不同之处,并检验它的优越性和缺陷。

所有动态语言(如Ruby,Groovy,Python等)及其相关的框架(如Ruby on rails)百家争鸣,尽管阅读本文的大部分Java开发者每天的大多数工作都是处理纯粹的Java,且未来多年都将如此,但这并不意味着他们不能学习新 的知识,在他们的兵器库中添加新的兵器,本文介绍YAML(YAML不是标记语言的简写)文件格式(使用Ruby on rails框架进行讲解,因为它所有的配置文件都是使用的YAML)以及它与XML和JSON的区别,最后讨论了YAML的优势和缺点。

空格缩进和JSON选项

YAML文件格式主要集中于空格缩进的概念,它用于指出数据的层次结构 – 而不是使用XML嵌套标记或JSON的大括号({})和方括号([]),实际上,它是JSON的一个超集,因此,在使用的时候,你可能需要采用JSON风 格的语法来跳出空格流,它的创始人将其形容为“为所有编程语言提供人性化的数据序列化标准”,以我的经验来看,其重点是人性化。
下面是一个使用空格缩进的YAML样例,创建YAML文件时不宜使用固定宽度字体,因为空格是很关键的。(参考侧边栏1:YAML和标签

JFrame:
defaultCloseOperation: JFrame.EXIT_ON_CLOSE
title: Test Frame
width: 800
height: 400
components:
- JTextArea:
name: textArea1
text: |
This is a really long text
that spans multiple lines (but preserves new lines).
It does not need to be escaped with special brackets,
CDATA tags, or anything like that
- JButton:
name: button2
text: Button 2

侧边栏1:YAML和标签
基于空格缩进的任一文件格式最常见的问题之一是如何解释标签,在这个YAML例子中,答案相当简单:它不支持标签。使用标签字符缩进代替空格将会导致处理异常。

随你喜欢,你可以在任何节点使用JSON风格语法或混合语法,例如,上面的例子可改为:

JFrame:
defaultCloseOperation: JFrame.EXIT_ON_CLOSE
title: Test Frame width: 800
height: 400
components:
- JTextArea:
name: textArea1
text: |
This is a really long text
that spans multiple lines (but preserves new lines).
It does not need to be escaped with special brackets,
CDATA tags, or anything like that
- JButton: {name: button2, text: Button 2} #JSON风格语法

在底层节点(即它们没有子节点,正如你猜测的那样,井号键在YAML中是用来注释的)切换使用JSON风格语法显得特别有用。

YAML结构组件

前面已经看了一个简单的YAML例子,下面让我们一起来了解一下YAML的结构:hash,list,和block literal。

hash(散列)

通过缩进子段和在关键字与值之间使用冒号(:)来分割实现hash的创建,如:

JFrame:
defaultCloseOperation: JFrame.EXIT_ON_CLOSE
title: Test Frame
width: 800
height: 400

还有一种方法就是使用与JSON兼容的大括号语法({})语法,每一对关键字/值使用逗号(,)分割,如:

JFrame: {defaultCloseOperation: JFrame.EXIT_ON_CLOSE, title: Test, Frame,
width: 800, height: 400}

list(清单)

通过在每个list元素前放一个减号(-)来创建list,与空格缩进一起构成了YAML的基石:

components:
- JTextArea
- Jbutton

还有一种方法就是使用JSON兼容的方括号([])语法,如:

components: [JTextArea, JButton]

block literal(文字块)

这是YAML的亮点,特别是与XML相比,它的CDATA显得相当简陋,block literal可以将大块文本细致地插入文件中,你可以使用竖线(|)指令在你的文本中保留新行,如:

text: |
This is a really long text
that spans multiple lines (but preserves new lines).
It does not need to be escaped with special brackets,
CDATA tags, or anything like that

YAML编译器将会从第一行的第一个文本字符开始编译(并丢掉所有的缩进空格),但是会在你的文本中保留新行。

另外,你还可以使用大于符号(>)告诉YAML编译器给所有新行加上条纹,并将输入的文本作为一个长行处理:

text: >
This is a really long text
that spans multiple lines (but preserves new lines).
It does not need to be escaped with special brackets,
CDATA tags, or anything like that
除了这两个指令之外,你还可以使用竖线和加号(|+),它给位于前面的空格加上条纹,保留新行和末尾的空格,还可以使用大于号和减号(>-),它给所有的空格加上条纹。

YAML VS. XML和JSON

正如你从前面例子中清楚地看到那样,YAML没有XML那么啰嗦了,大部分YAML文件内容就是真实的数据,没有了无穷尽的打开和关闭标记列表,在XML中,这些标记往往比它们描述的数据还大,YAML更适合你需要手工维护的数据文件类型。

YAML没有提供方案或DTD概念,因此无法验证文件格式是否符合你的预期,XML的啰嗦也有它的价值,但总的说来是因为XML的成熟使它具有大量额外的工具来验证它的格式,而YAML还没有。

JSON也适合与任何数据,它主要面向提高性能和文件尺寸的大小,因为它几乎不使用空格和关闭标签,然而,JSON文件的内容增加了复杂性,它的关 闭标识就象下地狱一样,这就是JavaFx代码(它基于JSON)中可见的最痛苦的了,在数据文件中,使用UI结构使结果更复杂,其复杂程度几乎使文件变 得无法理解。

查看http://jfx.wikia.com/wiki/JFXPresentation的JavaFx示例代码(点击“Edit this page”链接),请特别留心它是如何结束的。

}
}
}
}
]
}
}
center: bookPanel
}

掺和了{}结构和[]清单,使得手工维护大型的JSON风格的文件变得相当困难,YAML使用它的空格缩进方法巧妙地解决了这个问题,当然,无论何时,你都可以切换到JSON风格的语法(如在底层节点)。

解析YAML文件最常用的Java库是JvYAML(https://jvyaml.dev.java.net/), JRuby(在Java VM上运行动态语言的Ruby版本)在它的Ruby on Rails框架中的进出口使用JvYAML,JvYAML提供了文件一般处理的功能(在前面那个例子中,它返回了一个标准Java字符串、Long、 Map和List对象的嵌套体系结构),使用静态dump()方法保存为文件,然后使用静态load()方法载入,例如:

YAML.dump(Object data, Writer output);
Object data = YAML.load(Reader io);

参考侧边栏2:基于YAML的开源项目了解关于基于YAML的开源项目信息,以及如何在Java中装入一个说明的UI.

侧边栏2:基于YAML的开源项目
请原谅我在这里厚脸皮地介绍我们自己的开源项目,当我真的不知道除了JRuby外其他的基于YAML的开源项目,JRuby的Ruby on Rails框架实现严重依赖YAML,而不是XML或JSON,看看我的Java Builder库吧(http://www.javabuilders.org/),它利用YAML文件提供了一种方法定义屏幕控制、布局、事件线路和数据绑定,以实现将说明UI装入Java。

实际上,YAML文件真的非常简单,甚至你可以使用任何的文本编辑器都可以维护它,但有些专门的文本编辑器提供了语法加亮功能,这对维护工作很有帮助,对Eclipse而言,有Eclipse YAML editor(http://code.google.com/p/yamleditor/),对NetBeans而言,你可以使用来自Ruby包(http://www.netbeans.org/features/ruby/index.html)的YAML编辑器,然而,在NetBeans 6.1中的YAML编辑器并没有什么用处,它只支持YAML很小的一个子集(例如:它不支持block literal),希望在NetBeans 6.5中的YAML编辑器解决了这个问题。

我没有机会测试IntelliJ IDEA,但我推测它的Ruby on Rails插件
http://www.jetbrains.net/confluence/display/RUBYDEV/IntelliJ+IDEA+Ruby+Plugin)附带了YAML编辑器。

添加YAML工具

过分啰嗦的XML格式大多数情况下都是重复的,YAML和来自Java的用法在你的下一个项目中应该作为一个可选的非常棒的选择,在未来的学习中,请访问YAML的WiKi页面( http://en.wikipedia.org/wiki/YAML),它对YAML的高级特性如数据合并和数据计算有非常优秀的描述,也可以访问YAML的官方站点( http://www.yaml.org/)。