学习XML
XML
可扩展标记语言(extensible Markup Language)
XML特性
1.xml具有平台无关性,一门独立的标记语言。
2.xml具有自我描述性。
.XML文件是保存XML数据的一种方式,XML数据也可以以其他的方式存在。XML主要被设计用来存储数据,但不显示数据。
XML语法规则
.XML的语法规则相对简单,又很有逻辑性
1)XML文档声明必须写在第一行。
<?xml version="1.0" encoding="UTF-8"?>
<!--注释不能写在文档声明前-->
2)XML文档是由一个个的标记组成。
语法:
开放标记,也可称 开始标记:<标记名称>
闭合标记,也可称 结束标记:</标记名称>
<!--通过标记描述人名-->
<name>小名</name>
标记内容:位于开放标记和闭合标记之间的称为标记内容。
标记名称的定义必须遵循以下命名规则:
- 名称可以含字母、数字以及其他的字符
- 名称不能以数字或者标点符号开始
- 名称不能以字符“xml”(任何大小写的XML组合都不可以)开始
- 名称不能包含空格,不能包含冒号“ : ”
- 名称区分大小写
3)一个XML文档中,必须有且仅能有一个根标记。
<!--举例:<person></person>为根标记-->
<person>
<name>张三</name>
<age>18</age>
</person>
<!--以下为错误举例,没有根标记-->
<name>张三</name>
<age>18</age>
4)标记可以嵌套,但是不允许交叉。
<!--举例:语法正确-->
<person>
<name>张三</name>
<age>18</age>
</person>
<!--以下为错误举例,<age>和</name>不能交叉使用-->
<person>
<name>张三<age></name>
18</age>
</person>
5)标记的层级称呼(子标记,父标记,兄弟标记,后代标记,祖先标记)
<!--举例:语法正确-->
<persons>
<!--person是name的父标记-->
<person>
<!--name是person的子标记,也是后代标记-->
<name>张三</name>
<!--age是name的兄弟标记-->
<age>18</age>
</person>
<person>
<name>李四</name>
<age>19</age>
</persons>
</persons>
<!--name是persons的后代标记,persons是name的祖先标记-->
6)标记除了开始和结束,还有属性
<!--举例,属性可以根据需求编写-->
<persons>
<person id="001">
<name>张三</name>
<age>18</age>
</person>
<person id="002">
<name>李四</name>
<age>19</age>
</persons>
</persons>
7)注释
- 注释不能写在文档声明前
- 注释不能嵌套注释
注释格式:
- 开始:<!–
- 结束: -->
(这里都是两个“-”)
XML语言举例:
<?xml version="1.0" encoding="UTF-8"?>
<!--根标记-->
<persons>
</persons>
了解CDATA
CDATA(character data),不应该由XML解析器解析的文本数据。
- “<” 和 “&” 字符在 XML 元素中都是非法的。
- “<” 会产生错误,因为解析器会把该字符解释为新元素的开始。
- “&” 会产生错误,因为解析器会把该字符解释为字符实体的开始。
- 某些文本,比如 JavaScript 代码,包含大量 “<” 或 “&” 字符。为了避免错误,可以将脚本代码定义为 CDATA。
- CDATA 部分中的所有内容都会被解析器忽略。
- CDATA 部分由 “<![CDATA[" 开始,由 "]]>” 结束
Java解析XML面试题
问:Java中有几种XML解析方式?分别是什么?有什么样的优缺点?
答:四种,有SAX解析,DOM解析,JDOM解析,DOM4J解析
SAX解析
解析方式是事件驱动机制
SAX解析器,逐行读取XML文件解析 , 每当解析到一个标签的开始/结束/内容/属性时,触发事件。
优点:
- 分析能够立即开始
- 逐行加载,节省内存
- 不必解析整个文档,满足条件即可停止解析
缺点:
- 单向解析(解析后释放),无法定位文档层次,无法同时访问同一文档的不同部分数据,
- 无法得知时间发生时元素的层次,只能自己维护节点的父/子关系。
- 只读解析方式, 无法修改XML文档的内容。
DOM解析
在内存中加载整个文档并建立文档树模型,通过操作文档树来完成数据的获取 修改 删除等。
优点:
- 文档在内存中加载,允许对数据和结构做出更改。
- 访问是双向的,可以在任何时候在树中双向解析数据。
缺点:
- 文档全部加载在内存中 , 消耗资源大。
JDOM解析
目的是成为JAVA特定文档模型,它简化与XML的交互并且比使用DOM实现更快,由于是第一个Java特定模型,JDOM一直得到大力推广和促进。
优点:
- 使用具体类而不是接口,简化了DOM的API。
- 大量使用了Java集合类,方便了Java开发人员。
缺点:
- 没有较好的灵活性。
- 性能不是那么优异。
DOM4J解析
它是JDOM的一种智能分支,它合并了许多超出基本XML文档表示的功能,包括集成的XPath 支持、XML Schema支持以及用于大文档或流化文档的基于事件的处理。它还提供了构建文档表示的选项, DOM4J是一个非常优秀的Java XML API,具有性能优异、功能强大和极端易用使用的特点。同时它也是一个开放源码的软件。
DOM4J解析XML:
- 引入jar文件 dom4j.jar
- 创建一个指向XML文件的输入流
FileInputStream fis = new FileInputStream("xml文件的地址");
- 创建一个XML读取工具对象
SAXReader sr = new SAXReader();
- 使用读取工具对象, 读取XML文档的输入流 , 并得到文档对象
Document doc = sr.read(fis);
- 通过文档对象, 获取XML文档中的根元素对象
Element root = doc.getRootElement();
文档对象 Document
加载到整个内存的整个XML文档。
常用方法:
1.通过文档对象,获取XML文档中的根元素对象。
Element root = doc.getRootElement();
2.添加根节点
Element root = doc.addElement("根节点名称");
元素对象 Element
XML文档中的单个节点。
常用方法:
1.获取节点名称
String getName();
2.获取节点内容
String getText();
3.设置节点内容
String setText();
4.根据子节点的名称 , 获取匹配名称的第一个子节点对象.
Element element(String 子节点名称);
5.获取所有的子节点对象
List elements();
6.获取节点的属性值
String attributeValue(String 属性名称);
7.获取子节点的内容
String elementText(String 子节点名称);
8.添加子节点
Element addElement(String 子节点名称);
9.添加属性
void addAttribute(String 属性名,String 属性值);
DOM4J-XPATH解析XML
通过路径快速的查找一个或一组元素。
路径表达式:
- / :从根节点开始查找
- //:从发起查找的节点位置 查找后代节点 ***
- " . " 查找当前节点
- " . . "查找父节点
- @ 选择属性. *
属性使用方式:
- [@属性名=‘值’]
- [@属性名>‘值’]
- [@属性名<‘值’]
- [@属性名!=‘值’]
使用步骤:
通过Node类的两个方法,来完成查找:
(Node是Document 与Element 的父接口)
方法1:
// 根据路径表达式,查找匹配的单个节点
Element e = selectSingleNode("路径表达式");
方法2:
List<Element> es = selectNodes("路径表达式");
Java生成XML
步骤:
1.通过文档帮助器(DocumentHelper),创建空的文档对象
Document doc = DocumentHelper.createDocument();
2.通过文档对象,向其中添加根节点
Element root = doc.addElement("根节点名称");
3.通过根节点对象root,丰富子节点
Element e = root.addElement("元素名称");
4.创建一个文件输出流,用于存储XML文件
FileOutputStream fos = new FileOutputStream("要存储的位置");
5.将文件输出流,转换为XML文档输出流
XMLWriter xw = new XMLWriter(fos);
6.写出文档
xw.writer(doc);
7.释放资源
xw.close();
XStream的使用
快速的将Java中的对象,转换为XML字符串。
使用步骤:
1.创建XStream 对象
XStream x = new XStream();
2.修改类生成的节点名称 (默认节点名称为 包名.类名)
x.alias("节点名称",类名.class);
3.传入对象 , 生成XML字符串
String xml字符串 = x.toXML(对象);
举例:
Person p = new Person(1001, "张三", "不详");
XStream x = new XStream();
x.alias("haha", Person.class);
String xml = x.toXML(p);
System.out.println(xml);
JSON
(JavaScript Object Notation),JS对象简谱,是一种轻量级的数据交换格式。
对象格式:
java:
class Book{
private String name;
private String info;
get/set... //getter 与 setter
}
Book b = new Book();
b.setName(“《书名》”);
b.setInfo(“书的内容”);
js:
var b = new Object();
b.name = "《书名》";
b.info = "书的内容";
XML:
<book>
<name>书名</name>
<info>书的内容</info>
</book>
JSON:
{
"name":"《书名》",
"info":"书的内容"
}
一个对象, 由一个大括号表示:
括号中 描述对象的属性 . 通过键值对来描述对象的属性
(可以理解为, 大括号中, 包含的是一个个的键值对.)
格式:
键与值之间使用冒号连接,多个键值对之间使用逗号分隔。
键值对的键,应使用引号引住 (通常Java解析时,键不使用引号会报错。 而JS能正确解析。)
键值对的值,可以是JS中的任意类型的数据
数组格式
在JSON格式中可以与对象互相嵌套
[元素1,元素2…]
Java与JSON
将Java中的对象,快速的转换为JSON格式的字符串。
将JSON格式的字符串,转换为Java的对象。
GSON:
- 将对象转换为JSON的字符串
步骤:
1.引入jar包
2.在需要转换JSON字符串的位置编写如下代码即可:
String json = new Gson().toJSON(要转换的对象);
举例:将对象转换为JSON字符串
Book b = BookDao.find();
String json = new Gson().toJSON(b);
System.out.println(json);
- 将JSON的字符串转换为对象
步骤:
1.引入jar包
2.在需要转换Java对象的位置编写如下代码即可:
对象 = new Gson().fromJson(JSON字符串,对象类型.class);
举例:将JSON的字符串转换为对象
String json = "{\"id\":123}";
Book book = new Gson().fromJson(json, Book.class);
System.out.println(book);
FastJSON:
- 将对象转换为JSON字符串
步骤:
1.引入jar包
2.在需要转换JSON字符串的位置编写如下代码即可:
String json=JSON.toJSONString(要转换的对象);
举例:将对象转换为JSON字符串
Book b = BookDao.find();
String json=JSON.toJSONString(b);
System.out.println(json);
- 将JSON字符串转换为对象
步骤:
- 引入jar包
- 在需要转换Java对象的位置, 编写如下代码:
类型 对象名=JSON.parseObject(JSON字符串, 类型.class);
或
List<类型> list=JSON.parseArray(JSON字符串,类型.class);
举例: 将JSON字符串转换为对象
String json = "{\"id\":1}";
Book book = JSON.parseObject(json, Book.class);
System.out.println(book);