Java学习笔记@XML文档、解析、检索
笔者:unirithe
日期:11/13/2021
XML
概述
XMl是可扩展标记语言(eXtensible Markup Language) 的缩写,是一种数据表示格式,可以描述非常复杂的数据结构,常用于传输和存储数据
例如:
<?xml version="1.0" encoding="UTF-8"?>
<data>
</data>
XML的作用
- 用于进行存储和传输数据
- 作为软件的配置文件
XML的特点
- 纯文本,默认使用UTF8编码
- 可嵌套
XML的应用场景
- 作为消息进行网络传输
- 作为配置文件用于存储系统信息
使用规范
XML语法规范
- 文件后缀使用
.xml - 文档声明必须是第一行 ,如:
<? xml version="1.0" encoding="UTF-8" ?>
XML的标签(即元素)规范
-
标签由一对尖括号和合法标识符组成,比如
<name></name>,XML必须存在一个根标签,有且只能有一个 -
普通标签必须成对出现
-
特殊的标签可以不成对,但必须有结束的标记,如
<br/> -
标签中可定义属性,属性和标签名以空格隔开,属性值必须用引号引起来
-
标签嵌套要符合逻辑,如:
<user id = "1"> <name>unirithe</name> </user>
XML注释 (和HTML注释方式一样)
<!-- 注释内容 -->
XML转义字符
| 符号 | 表示方法 |
|---|---|
| < 小于 | < |
| > 大于 | > |
| & 和 | & |
| `单引号 | ' |
| "双引号 | " |
除了使用转义字符外, XML文件中可定义 CDATA区 <![CDATA[...任意内容...]]
XML 文档约束
文档约束:限定XML文件中的标签以及属性编写格式,主要有两种DTD和Schema
DTD约束
约束的文件后缀为.dtd
范例: (+号表示至少一个以上)
<!ELEMENT Schall(student+)>
<!ELEMENT student(name, sex)>
<!ELEMENT name(#PCDATA)>
<!ELEMENT sex(#PCDATA)>
使用方法
<? xml version="1.0" encoding="UTF-8" ?>
<School>
<student>
<name>unirithe</name>
<sex>man</sex>
</student>
<student>
<name>lucky</name>
<sex>woman</sex>
</student>
</School>
存在问题:无法约束具体的数据类型
Schema约束
作用:
- 可约束XML的数据类型
- 本身也是XML文件,受到其他约束文件的要求
- 后缀使用
.xsd
<?xml version="1.0" encoding="UTF-8" ?>
<schema xmlns="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.itcast.cn"
elementFormDefault="qualified">
<!-- targetNamespace 申明约束文档的位置 -->
<element name="School">
<complexType>
<sequence maxOccurs="unbounded"> <!-- 设置子元素为任意多个 -->
<element name="Student">
<complexType>
<sequence>
<element name = "name" type="string"/>
<element name = "sex" type ="string"/>
<element name = "age" type="int"/>
</sequence>
</complexType>
</element>
</sequence>
</complexType>
</element>
</schema>
使用
<?xml version="1.0" encoding="UTF-8" ?>
<School xmlns="http://www.itcast.cn"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.itcast.cn data.xsd">
<Student>
<name>unitihe</name>
<sex>man</sex>
<age>21</age>
</Student>
</School>
一般Schema约束都可以直接采取网络获取的方式,即配置xmlns属性,而无需自己编写
XML 解析技术
两大技术:SAX解析、DOM解析
DOM常见解析工具
| 名称 | 描述 |
|---|---|
| JAXP | SUN公司提供的一套XML的解析API |
| JDOM | 基于树型结构的开源项目,利用纯JAVA的技术对XML文档实现解析、生成、序列化以及多种操作 |
| *dom4j | 是JDOM的升级品,用来读写XML文件。具有性能优异、功能强大和极容易使用的特点,它的性能超过SUN公司官方的DOM技术,同时也是一个开放源代码的软件,Hibernate就用它读写配置文件 |
| jsoup | 功能强大DOM方式的XML解析开发包,尤其是对HTML解析更方便 |
常用解析工具:Dom4j

Document对象:整个XML文档
Node 对象
-
Element对象:标签
-
Atrribute对象:属性
-
Text对象:文本内容
Dom4j 快速入门
安装与配置
使用Dom4j只需要下载对应的驱动jar包即可在Java类中使用
适用于JDK8+版本的Dom4j-2.1.3版本下载地址
https://github.com/dom4j/dom4j/releases/download/version-2.1.3/dom4j-2.1.3.jar
下载完毕后导入到IDEA的项目中即可
另外,还可下载该版本对应的指导文档,下载地址:点这
Dom4j 的使用
Dom4j解析XML得到Document对象
SAXReader类
| 构造器/方法 | 描述 |
|---|---|
public SAXReader() |
创建Dom4J的解析器对象 |
Document read(String url) |
加载XML文件称为Document对象 |
Document类
| 方法 | 描述 |
|---|---|
| Element getRootElement() | 获得根元素对象 |
User.xml
<?xml version="1.0" encoding="UTF-8" ?>
<School >
<Student id="1">
<name>unitihe</name>
<sex>man</sex>
</Student>
<Student id="2">
<name>lucky</name>
<sex>woman</sex>
</Student>
</School>
package com.uni;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.junit.Test;
import java.io.InputStream;
public class Dom4jDemo {
@Test
public void test() throws Exception {
SAXReader saxReader = new SAXReader();
InputStream is = Dom4jDemo.class.getResourceAsStream("/userSchema.xml");
Document document = saxReader.read(is);
Element root = document.getRootElement();
System.out.println(root);
}
}
解析元素、属性文本的常用API
| 方法名 | 描述 |
|---|---|
List<Element> elements() |
得到当前元素下所有子元素 |
List<Element>elements(String name) |
得到当前元素下指定名字的子元素返回集合 |
Element element(String name) |
得到当前元素下指定名字的子元素,如果有多个则返回第一个 |
String getName() |
得到元素名字 |
String attributeValue(String name) |
通过属性名直接得到属性值 |
String elementType(子元素名) |
得到指定名称的子元素的文本 |
String getText() |
得到文本 |
范例:获取所有名为Student的一级子元素对象
List<Element> sons = root.elements("Student");
范例:获取第一个名为Student的一级子元素对象
Element userEle = root.element("Student");
范例:输出所有一级子元素的name值
List<Element> userEle = root.elements("Student");
for (Element element : userEle)
System.out.println(element.elementText("name"))
范例:根据元素获取属性值
List<Element> userEle = root.elements("Student");
for (Element element : userEle) {
Attribute idAttr = element.attribute("id");
System.out.println(idAttr.getName() + " -> " + idAttr.getValue());
}
更简便的方法:
System.out.println(element.attributeValue("id"));
XML 解析 案例
编写Java程序实现对XML文件进行解析,并创建对象存储内容
User.xml
<?xml version="1.0" encoding="UTF-8" ?>
<School >
<Student id="1">
<name>unitihe</name>
<sex>man</sex>
</Student>
<Student id="2">
<name>lucky</name>
<sex>woman</sex>
</Student>
</School>
class Student{
private int id;
private String name, sex;
public Student(){}
public Student(int id, String name, String sex) {
this.id = id;
this.name = name;
this.sex = sex;
}
@Override
public String toString() {
return "Student{" +
"id=" + id +
", name='" + name + '\'' +
", sex='" + sex + '\'' +
'}';
}
}
public class Dom4jDemo {
@Test
public void parseXMLData() throws Exception {
SAXReader saxReader = new SAXReader();
InputStream is = Dom4jDemo.class.getResourceAsStream("/user.xml");
Document document = saxReader.read(is);
Element root = document.getRootElement();
List<Element> stuEle = root.elements("Student");
List<Student> students = new ArrayList<>();
for (Element stu : stuEle) {
int id = Integer.valueOf(stu.attributeValue("id"));
String name = stu.elementText("name");
String sex = stu.elementText("sex");
students.add(new Student(id, name, sex));
}
for (Student student : students) {
System.out.println(student);
}
}
}
运行结果
Student{id=1, name='unitihe', sex='man'}
Student
XML 检索 XPath技术
Dom4j是先对XMl文件进行解析,然后再寻找数据,而XPath技术更适合 信息检索
XPath的特点
-
基于Dom4j开发的
-
提供了独树一帜的路径思想,更优雅高效
-
使用路径表达式来定位XMl文档中元素节点或属性节点
Xpath 快速入门
在使用XPath时,除了导入Dom4j.jar包以外,还需要导入jaxen-*.jar 下载点这
实现步骤
- 导入jar包 Dom4j 和 jaxen
- 通过 dom4j的SAXReader 获取 Document 对象
- 利用XPath提供的API,结合XPath的语法完成选取XML文档元素节点进行解析操作
Document中与Xpath相关的API如下:
| 方法名 | 描述 |
|---|---|
Node selectSingleNode("表达式") |
获取符合表达式的唯一元素 |
List<Node> selectNodes("表达式") |
获取符合表达式的元素结合 |
Xpath 的四大检索方案
- 绝对路径
- 相对路径
- 全文检索
- 属性查找
绝对路径 检索
采用绝对路径获取从根节点开始逐层的查找
| 方法名 | 描述 |
|---|---|
| /根元素/子元素/孙元素 | 从根元素开始,一级一级向下查找,不能跨级 |
package com.uni;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;
import org.junit.Test;
import java.util.List;
public class XPathDemo {
@Test
public void test() throws Exception {
SAXReader saxReader= new SAXReader();
Document document = saxReader.read(XPathDemo.class.getResourceAsStream("/user.xml"));
List<Node> nameNodes = document.selectNodes("/School/Student/name");
for (Node nameNode : nameNodes) {
Element nameEle = (Element) nameNode;
System.out.println(nameEle.getText());
}
}
}
相对路径 检索
@Test
public void test() throws Exception {
SAXReader saxReader= new SAXReader();
Document document = saxReader.read(XPathDemo.class.getResourceAsStream("/user.xml"));
Element root = document.getRootElement();
List<Node> nameNodes = root.selectNodes("./Student/name");
for (Node nameNode : nameNodes) {
Element nameEle = (Element) nameNode;
System.out.println(nameEle.getText());
}
}
全文检索
List<Node> nameNodes = document.selectNodes("//name");
// 相同效果
List<Node> nameNodes = document.selectNodes("//Student/name");
属性检索
- @属性名称
- 元素[@属性名称]
- 元素[@属性名称=值]
范例:@属性名称 检索
SAXReader saxReader= new SAXReader();
Document document = saxReader.read(XPathDemo.class.getResourceAsStream("/user.xml"));
Element root = document.getRootElement();
List<Node> nodes= document.selectNodes("//@id");
// 在这个案例里 @id 效果等同于Student[@id];
for (Node node : nodes) {
Attribute attr = (Attribute) node;
System.out.println(attr.getName() + " -> " + attr.getValue());
}
范例:元素[@属性名称] 检索
List<Node> nodes= document.selectNodes("//Student[@id]");
for (Node node : nodes) {
Element ele = (Element) node;
System.out.println(ele.elementText("name"));
}

浙公网安备 33010602011771号