XML:可扩展标记语言 eXtensible Markup Language
的缩写,是一种数据表示格式,可以描述非常复杂的数据结构,常用于传输和存储数据。如果把 XML 内容存为文件,那么该文件就是 XML 文件。
特点:纯文本,默认使用 UTF-8
编码;可嵌套。
作用:用于进行存储数据和传输数据;作为配置文件用于存储系统的信息。
创建:创建一个 XML 类型的文件,文件的后缀名为 .xml
,如:hello_world.xml
。
XML 的标签(元素)语法规则:
/
标记;
;
;
,其中可以写任何内容,快捷键:CD
;替代 | 特殊字符 |
---|---|
< | < 小于 |
> | > 大于 |
& | & 和号 |
' | ‘ 单引号 |
" | “ 引号 |
右键点击文件选择 Open in Browser
,用浏览器打开显示如下
文档约束:用来限定 XML 文件中的标签以及属性应该怎么写,程序员必须依照文档约束的规定来编写 XML 文件。
XML 文档约束方式分为:DTD 约束和 schema 约束。
依据文档约束来编写 XML 文档的步骤:
注意:
DTD 约束文档后缀为
.dtd
;schema 约束文档也是一个 XML 文件,后缀为.xsd
。DTD 不能约束具体的数据类型;schema 可以约束具体的数据类型。
XML 文件解析:使用程序读取 XML 文件中的数据。
两种解析方式:SAX 解析和 DOM 解析(解析常用的技术框架:Dom4j)。
DOM 解析文档对象模型:
Document
对象代表整个 XML 文档;Element
对象代表标签(元素);Attribute
对象代表属性;Text
对象代表文本内容。注意:
Element
对象、Attribute
对象以及Text
对象都实现了Node
接口,都是节点类型(最高类型)。
首先需要在官网下载 Dom4j 框架,然后导入 jar 包。
解析的步骤:
SAXReader saxReader = new SAXReader();
;read
方法把 XML 文件加载到内存中成为一个 Document 文档对象;getRootElement
方法来获取根元素对象;方法名 | 说明 |
---|---|
List elements() | 得到当前元素下所有子元素对象 |
Element element(String var1) | 得到当前元素下指定名字的子元素对象返回集合 |
List attributes() | 得到当前元素下的所有属性对象 |
Attribute attribute(String var1) | 得到当前元素下指定属性名的属性对象 |
String getText() | 得到当前元素下的文本,返回值为 String 类型 |
String getTextTrim() | 得到当前元素下的文本(去掉前后空格),返回值为 String 类型 |
注意:
- 在第二个方法中,若参数中指定的名字对应不止一个子元素对象,则默认提取第一个子元素对象。
- 获取到子元素对象后,可以继续调用
getName
方法和getText
方法获取元素的名字和文本。- 获取到属性对象后,可以继续调用
getName
方法和getValue
方法获取属性的名称和对应的值。- 获取子元素对象后可以继续调用
elements
方法,进一步获取子元素的子元素对象。- API 很灵活,用到时再去查。
解析结果
注意:
- 最好使用
Class
对象调用getResourceAsStream
来产生字节输入流,这样可以避免后续模块名发生改变而可能出现的错误。getResourceAsStream
方法中的/
可以直接去src
下寻找文件,而且必须是正斜杠。- 先获取元素对象或属性对象,然后再进行进一步操作。
需求:将指定 XML 文件中的数据封装为 List 集合,其中每个元素是实体类
Contact
。
实现
运行结果
注意:获取属性值或子元素对象文本有两种方法:先获取属性对象或子元素对象,然后调用方法;也可以直接调用以下方法获取。
方法名 | 说明 |
---|---|
String attributeValue(String var1) | 直接获取元素的属性值 |
String elementTextTrim(String var1) | 直接获取该元素下子元素的文本(去掉前后空格) |
代码
package com.dom4j;
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
public class Demo02 {
public static void main(String[] args) throws Exception {
SAXReader saxReader = new SAXReader();
InputStream is = Demo02.class.getResourceAsStream("/XMLdata/data01.xml");
Document document = saxReader.read(is);
List<Contact> list = Demo02.praseToList(document);
System.out.println(list);
}
public static List<Contact> praseToList(Document document) {
// 定义一个 list 集合用于存储 Contact 对象
List<Contact> list = new ArrayList<>();
Element root = document.getRootElement();
// 根元素的子元素
List<Element> elements = root.elements("contact");
// 遍历根元素的子元素
for (Element element : elements) {
// 每有一个子元素,就创建一个 Contact 对象
Contact con = new Contact();
// 子元素的属性对象值
con.setId(Integer.valueOf(element.attributeValue("id")));
con.setVip(Boolean.valueOf(element.attributeValue("vip")));
con.setName(element.elementTextTrim("name"));
con.setAge(Integer.valueOf(element.elementTextTrim("age")));
con.setHobby(element.elementTextTrim("hobby"));
// // 取子元素的子元素对象
// List elems = element.elements();
// for (Element elem : elems) {
// switch (elem.getName()) {
// case "name":
// con.setName(elem.getTextTrim());
// break;
// case "age":
// con.setAge(Integer.valueOf(elem.getTextTrim()));
// break;
// case "hobby":
// con.setHobby(elem.getTextTrim());
// break;
// default:
// break;
// }
// }
list.add(con);
}
return list;
}
}
XPath 作用:检索 XML 文件中的信息。
XPath 使用路径表达式来定位 XML 文档中的元素节点或属性节点。
检索的步骤:
SAXReader saxReader = new SAXReader();
;read
方法把 XML 文件加载到内存中成为一个 Document 文档对象;方法名 | 说明 |
---|---|
Node selectSingleNode(String var1) | 获取符合路径表达式的唯一元素 |
List selectNodes(String var1) | 获取符合路径表达式的元素集合 |
元素查找的路径表达式 | 说明 |
---|---|
/根元素/子元素/子元素 | 绝对路径 |
./子元素/子元素 | 相对路径,其中 . 表示当前元素 |
//元素 | 在全文搜索全部这个元素 |
//元素1/元素2 | 在全文元素 1 下找一级元素 2 |
//元素1//元素2 | 在全文元素 1 下找全部元素 2 |
注意:
/
表示一级元素,//
表示全部元素。
根据属性查找属性对象或元素对象的路径表达式 | 说明 |
---|---|
//@属性名 | 查找所有属性对象 |
//元素[@属性名] | 查找带有指定属性名的元素对象 |
//元素//[@属性名 = '值'] | 查找带有指定属性名,并且属性值相等的元素对象 |
注意:路径表达式都是正斜杠
/
。
元素查找
属性查找或元素查找
工厂设计模式:Factory Pattern 是 Java 中常用的设计模式之一,属于创建型模式,提供了一种获取对象的方式。
作用:
装饰设计模式:创建一个新类,包装原始类,从而在新类中提升原来类的功能。
步骤:
作用:在不改变原类的基础上,动态地扩展一个类的功能。
如:InputStream
是抽象父类,FileInputStream
是实现子类、BufferedInputStream
是实现子类,是装饰类,读写性能提高。
实践:模拟 IO 流。
注意:在 main 方法中,
is
的实际类型为FileInputStream
,所以在使用构造器创建bis
对象时,传入的参数实际类型为FileInputStream
,之后在装饰类调用read
方法时,调用的是原始类(实现类)中的read
方法(多态特点)。