文章目录
- XML
- 基础语法
- java中对XML的生成与解析方式
- SAX解析
- DOM解析
- JDOM解析
- DOM4J解析
- DOM4J相关语法
- XML文件的解析
- 根据XPath解析
- 生成XML
- XStream
- JSON
- 概述
- 基础语法[^2]
- 简单的解析语法
XML
XML 全称可扩展标记语言(EXtensible Markup Language),是一种标记语言,很类似 HTML,但是 XML 不是 HTML 的替代。XML 的设计宗旨是传输数据,而非显示数据。XML具有自我描述性,是 W3C 的推荐标准。
在现在,XML可以运用的场合有:
网络数据传输(主流:json)
数据存储(主流:数据库/文件管理系统)
配置文件(主流:xml)
基础语法
在XML文档的开头,书写XML的文档声明,例如:
<?xml version="1.0" encoding="utf-8"?>
xml文档主体内容由一个个标记组成。标记的语法如下:
开始标记(开放标记):<标记名称>
结束标记(闭合标记):</标记名称>
标记内容:开始/结束标记之间
例如:
<book>
这是一本书
</book>
标记名称的命名规则:
- 可以含字母、数字以及其他字符
- 不能数字或符号开始
- 不能以xml开头(含大小写)
- 不含空格,不能包含冒号
- 区分大小写
一个xml文档有且仅有一个根标记。标记可嵌套,不允许交叉。我们可以用这样的名称称呼标记层级:子标记、父标记、兄弟标记、后代标记、祖先标记。标记名称允许重复,可以包含属性。在开始标记描述速,属性名之间不允许重复,属性值必须被引号引住。例如:
<book id="1001">
这是一本书
</book>
可以在xml文档中书写注释。注释不能写在文档声明前,不能嵌套注释。格式如下:
<!-- 这是一个注释 -->
这是一个规范的xml文档的示例:
<?xml version="1.0" encoding="utf-8"?>
<books>
<book id="1001">
<name>书名称</name> <!-- 这是书的名称 -->
<author>
<name>无名氏</name>
<age>18</age>
</author>
</book>
<book id="1002">
<type>少儿读物</type>
<name>十万个为什么</name>
</book>
</book>
当一段话不想被xml解析器解析(例如js语言语法)的时候,可以用<![CDATA[^ 不解析的内容 ]]> 包含。例如:
<code lang="html">
<![CDATA[^<p>正文</p>]]>
</code>
java中对XML的生成与解析方式
在java中,XML的解析方式分为四种:
- SAX解析
- DOM解析
- JDOM解析
- DOM4J解析
其中前两种属于基础方法,是官方提供的平台无关的解析方式;后两种属于扩展方法,它们是在基础的方法上扩展出来的,只适用于java平台。
SAX解析
SAX的解析是逐行读取的,解析方式是事件驱动机制(解析到特殊位置会有特定事件发生),即每当解析到标签的 开始/结束/内容/属性 时触发事件。
优点
- 分析能立即开始
- 逐行解析,节省内存,有助于解析大于系统内存的文档
- 有时不必解析整个文档,可以在某个条件满足时停止解析
缺点
- 单向解析,无法定位文档层次,无法同时访问同一文档不同部分数据
- 无法得知元素层次,只能自己维护节点的父/子关系
- 只读解析方式,无法修改文档内容
DOM解析
DOM解析是w3c的解析标准。DOM解析会将xml文件整个读入内存中,并在内存中建立文档树模型。
优点
- 允许对数据和结构做出更改
- 访问双向,可以在任何时候在树中双向解析数据
缺点
- 文档加载在内存,消耗资源大
但是事实上DOM解析的缺点可以忽略不计。因为在实际运用中很少存在xml文件无法在一次解析中完全装入内存的情况。因此大多数的解析采用的都是DOM解析。
JDOM解析
JDOM是java特有的、基于DOM的解析方式。它有如下特征1:
- 仅使用具体类,而不使用接口。
- API大量使用了Collections类。
因此JDOM大大方便了java程序员。不过由于JDOM有一个更好的替代工具,因此JDOM的应用相对而言并不是特别的多。
DOM4J解析
DOM4J具有如下特征1:
- JDOM的一种智能分支,它合并了许多超出基本XML文档表示的功能。
- 它使用接口和抽象基本类方法。
- 具有性能优异、灵活性好、功能强大和极端易用的特点。
- 是一个开放源码的文件
DOM4J在4种解析方式中有最好的性能和最好的支持,因此在java中常用的解析方式为DOM4J。
DOM4J相关语法
XML文件的解析
示例步骤如下:
- 在解析之前需要引入DOM4J的jar包 dom4j.jar。
- 创建指向XML文件的输入流(以文件输入流为例)
InputStream fis = new FileInputStream("文件名.txt");
- 创建XML读取工具对象 SAXReader
SAXReader sr = new SAXReader();
- 使用读取工具对象,读取输入流,获取文档对象 Document
Document doc = sr.read(fis);
- 通过文档对象,获取xml文档中的根元素对象 Element
Element root = doc.getRootElement();
Document 代指要读取的xml文档
Element
对于 Document,可以用如下方法添加根节点:
Element e = doc.addElement("根节点名称")
Element
返回值 | 方法 | 描述 |
String | getName() | 返回当前节点的标记名称 |
String | getText() | 返回标签体 |
void | setText(String s) | 设置标签体内容 |
String | attributeValue(String s) | 返回属性值,s表示属性名称 |
void | addAttribute(String key, String value) | 添加属性 |
Element | element(String name) | 根据name获取第一个子节点 |
List<Element> | elements() | 返回子节点的列表 |
String | elementText(String s) | 返回子节点内容,s表示子标签名称 |
根据XPath解析
XPath的格式如下:
标记 | 注释 |
/ | 从根节点开找 |
// | 查找后代节点 |
. | 查找当前节点 |
… | 查找父节点 |
@ | 选择属性,例如: [@属性名=‘值’] [@属性名>‘值’] [@属性名<‘值’] [@属性名!=‘值’] |
例如,通过文档对象+xpath,查找所有的name节点
List<Node> names = doc.selectNodes("//name");
// 查找所有名为name的节点,即根节点的后代节点中所有叫做name的。Node是Element的子类
生成XML
生成XML文档的一般步骤如下:
- 通过文档帮助器创建空的文档对象
Document doc = DocumentHelper.createDocument();
- 通过文档对象,添加根节点
Element root = doc.addElement("根节点名称");
- 丰富子节点
- 创建文件输出流,用于储存xml
OutputStream fos = new FileOutputStream("文件名");
- 文档输出流转为xml输出流
XMLWriter xw = new XMLWriter(fos);
- 写出文档
xw.write();
- 释放资源
xw.close();
XStream
根据beans对象自动生成xml字符串。一般的步骤如下:
1、创建XStream对象
XStream x = new XStream();
2、修改某个类型生成的根节点(可选,默认为包名.类名)
x.alias("person",Person.class); // 修改类型为根节点
3、传入对象,开始生成
String xml = x.toXML(p);
JSON
概述
JSON全称 JS对象简谱(JavaScript Object Notation),是一种轻量级的数据交换格式。在1999出现。由于json解析速度快,因此在2005~2006年,随着谷歌和雅虎的大力推荐,json开始取代xml的地位。
基础语法2
JSON是一个标记符的序列。这套标记符包含六个构造字符、字符串、数字和三个字面名。
JSON是一个序列化的对象或数组。
六个构造字符分别为:
[ 左方括号
{ 左大括号
] 右方括号
} 右大括号
: 冒号
, 逗号
在这六个构造字符的前或后允许存在无意义的空白符。
值可以是对象、数组、数字、字符串或者三个字面值(false、null、true)中的一个。值中的字面值中的英文必须使用小写。
对象由花括号括起来的逗号分割的成员构成,成员是字符串键和上文所述的值由逗号分割的键值对组成。
{"name": "John Doe", "age": 18, "address": {"country" : "china", "zip-code": "10000"}}
数组是由方括号括起来的一组值构成。
[3, 1, 4, 1, 5, 9, 2, 6]
字符串与C或者Java的字符串非常相似。字符串是由双引号包围的任意数量Unicode字符的集合,使用反斜线转义。一个字符(character)即一个单独的字符串(character string)。
数字也与C或者Java的数值非常相似。除去未曾使用的八进制与十六进制格式。除去一些编码细节。
一些合法的JSON的实例:
{
"sites": [
{ "name":"CSDN" , "url":"csdn.net" },
{ "name":"google" , "url":"www.google.com" },
{ "name":"微博" , "url":"www.weibo.com" }
]
}
简单的解析语法
java官方未提供官方的json解析工具,json的解析借助第三方工具完成。常见的第三方工具有谷歌的Gson和阿里巴巴的fastjson。部分解析语法如下:
Gson
String json = new Gson.toJSON(对象);
对象 = new Gson.fromJson(JSON字符串,对象类型.class);
fastJson3
public class Person {
@JSONField(name = "AGE")
private int age;
@JSONField(name = "FULL NAME")
private String fullName;
@JSONField(name = "DATE OF BIRTH")
private Date dateOfBirth;
public Person(int age, String fullName, Date dateOfBirth) {
super();
this.age = age;
this.fullName= fullName;
this.dateOfBirth = dateOfBirth;
}
// 标准 getters & setters
}
可以使用 JSON.toJSONString() 将 Java 对象转换换为 JSON 对象:
private List<Person> listOfPersons = new ArrayList<Person>();
@Before
public void setUp() {
listOfPersons.add(new Person(15, "John Doe", new Date()));
listOfPersons.add(new Person(20, "Janette Doe", new Date()));
}
@Test
public void whenJavaList_thanConvertToJsonCorrect() {
String jsonOutput= JSON.toJSONString(listOfPersons);
}