文章目录

  • 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>

标记名称的命名规则:

  1. 可以含字母、数字以及其他字符
  2. 不能数字或符号开始
  3. 不能以xml开头(含大小写)
  4. 不含空格,不能包含冒号
  5. 区分大小写

一个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的解析方式分为四种:

  1. SAX解析
  2. DOM解析
  3. JDOM解析
  4. DOM4J解析

其中前两种属于基础方法,是官方提供的平台无关的解析方式;后两种属于扩展方法,它们是在基础的方法上扩展出来的,只适用于java平台。

SAX解析

SAX的解析是逐行读取的,解析方式是事件驱动机制(解析到特殊位置会有特定事件发生),即每当解析到标签的 开始/结束/内容/属性 时触发事件。

优点

  1. 分析能立即开始
  2. 逐行解析,节省内存,有助于解析大于系统内存的文档
  3. 有时不必解析整个文档,可以在某个条件满足时停止解析

缺点

  1. 单向解析,无法定位文档层次,无法同时访问同一文档不同部分数据
  2. 无法得知元素层次,只能自己维护节点的父/子关系
  3. 只读解析方式,无法修改文档内容

DOM解析

DOM解析是w3c的解析标准。DOM解析会将xml文件整个读入内存中,并在内存中建立文档树模型。

优点

  1. 允许对数据和结构做出更改
  2. 访问双向,可以在任何时候在树中双向解析数据

缺点

  • 文档加载在内存,消耗资源大

但是事实上DOM解析的缺点可以忽略不计。因为在实际运用中很少存在xml文件无法在一次解析中完全装入内存的情况。因此大多数的解析采用的都是DOM解析。

JDOM解析

JDOM是java特有的、基于DOM的解析方式。它有如下特征1

  1. 仅使用具体类,而不使用接口。
  2. API大量使用了Collections类。

因此JDOM大大方便了java程序员。不过由于JDOM有一个更好的替代工具,因此JDOM的应用相对而言并不是特别的多。

DOM4J解析

DOM4J具有如下特征1

  1. JDOM的一种智能分支,它合并了许多超出基本XML文档表示的功能。
  2. 它使用接口和抽象基本类方法。
  3. 具有性能优异、灵活性好、功能强大和极端易用的特点。
  4. 是一个开放源码的文件

DOM4J在4种解析方式中有最好的性能和最好的支持,因此在java中常用的解析方式为DOM4J。

DOM4J相关语法

XML文件的解析

示例步骤如下:

  1. 在解析之前需要引入DOM4J的jar包 dom4j.jar
  2. 创建指向XML文件的输入流(以文件输入流为例)
InputStream fis = new FileInputStream("文件名.txt");
  1. 创建XML读取工具对象 SAXReader
SAXReader sr = new SAXReader();
  1. 使用读取工具对象,读取输入流,获取文档对象 Document
Document doc = sr.read(fis);
  1. 通过文档对象,获取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文档的一般步骤如下:

  1. 通过文档帮助器创建空的文档对象
Document doc = DocumentHelper.createDocument();
  1. 通过文档对象,添加根节点
Element root = doc.addElement("根节点名称");
  1. 丰富子节点
  2. 创建文件输出流,用于储存xml
OutputStream fos = new FileOutputStream("文件名");
  1. 文档输出流转为xml输出流
XMLWriter xw = new XMLWriter(fos);
  1. 写出文档
xw.write();
  1. 释放资源
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);
}