谈对XML与JSON的理解
1.XML
- 基本概念:一种独立的可拓展标记语言,本质上也是一门独立的语言,是可以自行编译的代码(而不仅仅是.xml的文本文件,.xml仅仅是其存储为文件时的格式而已)。我们利用XML来将各种信息封装成一个对象并转换成XML的代码,并按照文本的形式存放,从而实现了跨语言(平台无关性)的传递。
- 那,这种语言的存在意义是什么?——让程序员们在传输多个不同类型的数据时不用在为“如何将这些毫不相干的数据分隔开、若用标识符的话在解析的时候一定得交代好商量好标识符是啥”而犯愁了,大大提高了传递数据、解析数据时的效率。
- 注:实际应用中,如今更多时候会选择JSON语言,性质一样,但解析效率大大提高。
XML书写格式
先来一段例子
<?xml verson="1.0" encoding="UTF-8"?>
<Persons>
<person id = "1001">
<name>小明</name>
<ages>18</ages>
</person>
<person id = "1002">
<name>小王</name>
<ages>20</ages>
</person>
</Persons>
几大要素:
!!!文档声明
1.元素(element)/节点
2.属性
先说文档说明,其格式一定一定不要写错:
<?xml version=“1.0” encoding="UTF-8"?>
尤其要注意两个加粗的地方,那里不能多出来空格位,否则会报错:处理指令必须以目标名称开头
除此之外,这里面任何一个字母、数字、符号等一定都不能缺漏,否则会报出一个声东击西的错误:应该有伪属性名 看到这个,很多菜鸟包括我都是第一时间去到我们编写的对象之中去找错,如果对象中内容较多,这找错无异于大海捞针,所以一定一定不要写错文件声明!
1.元素
例子中我们所看到的用<>包住的即是元素,
最外层的元素Persons-对标于-我们的对象的类
第二层的元素person-对标于-我们的对象
最内层的诸多元素name、ages-对标于我们对象的属性
在创建时,
最外层的元素如果我们不修改的话,默认就是对象的类名;
格式:外层元素必须”有头有尾“,把内有元素包裹起来;
<外层元素>
</外层元素>
<内层元素1>内容</内层元素1>
<内层元素2>内容</内层元素2>
内层元素则把内容包在内头就好。
2.属性
例子中我们看到的id即是属性,在一个属性即一个<>中可含有多个属性,但同一个属性的话名字不可重复;不同<>里可含有同一属性。
格式:属性名 = ”数值“
解析
解析方式很多,包括SAX解析、DOM解析、JDOM解析和DOM4J解析。我们主要讲DOM4J解析:
DOM4J解析
// 创建流对象
FileInputStream fis = new FileInputStream("D://xml测试文档.xml");
// 创建读取对象
SAXReader sr = new SAXReader();
// 读取:获取read出来的Document对象
Document get = sr.read(fis);
// 获取根对象
Element root = get.getRootElement();
System.out.println("root = "+ root.getName());
// 获取子节点:上一个接下一个去调用element得到元素
Element son1 = root.element("book");
System.out.println("son1 = "+ son1.getName()); //得到元素的名字
System.out.println("son1.getText = "+son1.getText()); //得到元素的内容
结果为:
root = Books
son1 = book
son1.getText =
sonSon.getText() = 肖1
list.get(0) = book
list.get(i).element(age).getText() = 20
list.get(1) = book
list.get(i).element(age).getText() = 22
1001
list.get(0) = book
list.get(i).element(age).getText() = 20
1001
list.get(1) = book
list.get(i).element(age).getText() = 22
1001
过程就是创建io流对象、创建读取对象、读取、获取根节点(根元素)、解析—即调用各类方法来得到XML的内容。
常用的调用方法有:
.getName():获取元素的名称
.element():获取元素,得到Element类型的返回值
.elements():获取所有的元素,返回的是Element类型的LIst数组
.getText():获取内容,调用对象为元素(外层元素的内容为三行空格,内层元素则是存储的具体信息:小明、18这些)
.attributeValue():获取属性值,调用对象自然为其所在的外层元素
XPATH解析
FileInputStream fis = new FileInputStream("D://xml测试文档.xml");
SAXReader sr = new SAXReader();
Document doc = sr.read(fis);
System.out.println("get.selectNodes(//age) = "+ doc.selectSingleNode("//age").getName());
System.out.println("get.selectNodes(//age).getText() = "+ doc.selectSingleNode("//age").getText());
List<Node> list = doc.selectNodes("//name");
for (int i=0;i<list.size();i++){
System.out.println("list.get(i).getText() = "+ list.get(i).getText());
}
结果为:
get.selectNodes(//age) = age
get.selectNodes(//age).getText() = 20
list.get(i).getText() = 肖1
list.get(i).getText() = 肖2
过程前三步一样,区别就在解析步,调用方法是.selectNodes()、.selectsingleNode(),节点观念
但XPATH最大的特点是路径表达式:
- /:从根节点开始查找
- //:从标识元素开始查找,例://name即从name开始,而非根的Persons开始,那样要表述完从根到该元素的完整路径:/Persons//person//name
- .:查找当前节点
- …:查找父节点
路径表达式用在.selectNodes()中
XStream生成XML
既然也是将信息按对象形式封装成文本,那么通过Java是否可以写出XML呢?自然是可以的,通过XStream可以实现这一点。XStream实现的是将信息转为String类型字符串,便于输出到控制台查看,而不是创建文本将信息写入。以下为实例:
public static void main(String[] args) {
//1. 创建对象,封装信息
Person p = new Person();
p.setName("肖111");
p.setAge("19");
//2. 创建XStream对象
XStream xs = new XStream();
//3. 通过.alias()修改节点名称
xs.alias("Person",Person.class);
//4. 输出为字符串
System.out.println(xs.toXML(p));
}
public static class Person{
private String name;
private String age;
public void setName(String name) {
this.name = name;
}
public void setAge(String age) {
this.age = age;
}
}
结果为:
<Person>
<name>肖111</name>
<age>19</age>
</Person>
过程在注释中讲解较为详细,不再赘述。
上面讲到XStream写出来的是String类型字符串而非写出为文本文档,那这次说明如何写成为文本文档:
public static void main(String[] args) throws IOException {
Document doc = DocumentHelper.createDocument();
//1. 往里添加元素:addelement()
Element root = doc.addElement("Persons");
Element node2 = root.addElement("age");
Element node1 = root.addElement("name");
//2. 往元素里头添加内容:.setText()
node1.setText("小肖1");
node2.setText("20");
//3. 输出出去,就是设置文件输出流
FileOutputStream fos = new FileOutputStream("D://Java生成XML文档.xml");
XMLWriter xml = new XMLWriter(fos);
xml.write(doc);
xml.close();
}
结果是:在D盘创建了“Java生成XML文档.xml”文档,其中内容是:
<?xml version="1.0" encoding="UTF-8"?>
<Persons><age>20</age><name>小肖1</name></Persons>
Ctrl+Alt+L快捷键格式化后:
<?xml version="1.0" encoding="UTF-8"?>
<Persons>
<age>20</age>
<name>小肖1</name>
</Persons>
JSON
性质与XML一样,同样是独立的拓展性标记语言,但因其解析速度更快效率更高而在现情况下使用得更多。
1.种类:分为谷歌开发的Gson,以及阿里开发的Fastjson。前者使用相对更多,后者使用上相对而言虽然更加简单,但时有漏洞出现。
2.格式:
一个{}即是一个对象
内容存储:
(1)可理解为键值对的概念,格式是—“键”:值 (当值为String类型字符串时才要用“ ”引住,否则不用)
(2)每个键值对之间—用逗号分开
(3)若出现数组—其值用[ ]引住,多个值之间用逗号隔开
(4)常用方法:
.get():传入键名(要用“ ”引住),得到对应的值
数组中:.get(“键名”).get(下标)
实例:
public static void main(String[] args) {
//1. 创建对象,封装信息
Books b = new Books();
b.setName("好书1");
b.setNum("220");
//2. 创建Gson对象,调用toJson()并传入信息对象后即可创建
Gson g = new Gson();
System.out.println(g.toJson(b));
}
public static class Books{
private String name;
private String num;
public void setName(String name) {
this.name = name;
}
public void setNum(String num) {
this.num = num;
}
}
过程也很简单,就是创建信息对象、创建Gson对象、调用.toJson()方法并传入信息对象即创建;要解析的话,调用的方法是.fromJson(),非常好便于理解。