文章目录
6.1 官方文档
6.1.1 地址: https://www.w3school.com.cn/xml/index.asp.
6.1.2 离线文档: W3School 离线手册(2017.03.11 版).chm
6.2 为什么需要 XML
- 需求 1 : 两个程序间进行数据通信
- 需求 2 : 给一台服务器,做一个配置文件,当服务器程序启动时,去读取它应当监听的端口号、还有连接数据库的用户名和密码
- spring 中的 ico 配置文件:beans.xml mybatis XXXMapper.xml tomcat server.xml web.xml maven pom.xml
- 能存储复杂的数据关系
6.3 XML 技术用于解决什么问题
-
解决程序间数据传输的问题:=> json
比如 qq 之间的数据传送,用 xml 格式来传送数据,具有良好的可读性,可维护性
-
xml 可以做配置文件
① xml 文件做配置文件可以说非常的普遍
② 比如我们的 tomcat 服务器的 server.xml,web.xml -
xml 可以充当小型的数据库 => 程序自己的数据格式存放
xml 文件做小型数据库,也是不错的选择,我们程序中可能用到的数据,如果放在数据库中读取不合适(因为你要增加维护数据库工作),可以考虑直接用 xml 来做小型数据库 ,而且直接读取文件显然要比读取数据库快
6.4 XML 快速入门
6.4.1 需求分析/图解
- 需求: 使用 idea 创建 students.xml 存储多个学生信息
<?xml version="1.0" encoding="UTF-8" ?>
<!--
解读:
1 xml :表示该文件的类型 xml
2 version="1.0"版本
3 encoding="UTF-8" 文件编码
4. students: root元素/根元素, 程序员自己来定
5. <student></student> 表示students一个子元素, 可以有多个
6. id就是属性 name, age, gender 是student元素的子元素
-->
<students>
<student id="100">
<name>jack</name>
<age>10</age>
<gender>男</gender>
</student>
<student id="200">
<name>mary</name>
<age>18</age>
<gender>女</gender>
</student>
</students>
6.4.2 完成步骤
- 步骤 1
- 步骤 2
- 步骤 3
- 创建 xml 步骤 4
6.5 XML 语法
6.5.1 一个 XML 文件分为如下几部分内容
- 文档声明
- 元素
- 属性
- 注释
- CDATA 区 、特殊字符
6.5.2 文档声明
<?xml version="1.0" encoding="UTF-8" ?>
-
XML 声明放在 XML 文档的第一行
-
XML 声明由以下几个部分组成:
① version —文档符合 XML1.0 规范,我们学习 1.0
② encoding —文档字符编码,比如 “utf-8”
6.5.3 元素
1、元素语法要求:
- 每个XML文档必须有且只有一个根元素
- 根元素是一个完全包括文档中其他所有元素的元素
- 根元素的起始标记要放在所有其他元素的起始标记之前
- 根元素的结束标记要放在所有其他元素的结束标记之后
- 应用实例:
<?xml version="1.0" encoding="utf-8" ?>
<!--
解读:
1.每个XML文档必须有且只有一个根元素。
2.根元素是一个完全包括文档中其他所有元素的元素。
3.根元素的起始标记要放在所有其他元素的起始标记之前。
4.根元素的结束标记要放在所有其他元素的结束标记之后
5.XML元素指XML文件中出现的标签,一个标签分为开始标签和结束标签,一个标签有如下几种书写形式
包含标签体:<a>www.sohu.cn</a>
不含标签体的:<a></a>, 简写为:<a/>
6.一个标签中也可以嵌套若干子标签。但所有标签必须合理的嵌套,绝对不允许交叉嵌套
7. 叫法student 元素,节点,标签
-->
<students>
<student id="100">
<name>jack</name>
<age>10</age>
<gender>男</gender>
</student>
<student id="200">
<name>mary</name>
<age>18</age>
<gender>女</gender>
</student>
<school>清华大学</school>
<city/>
</students>
2、 XML 元素指 XML 文件中出现的标签,一个标签分为开始标签和结束标签,一个标签有如下几种书写形式,例如:
- 包含标签体:
<a>www.sohu.cn</a>
- 不含标签体的:
<a></a>
,简写为:<a/>
- 一个标签中也可以嵌套若干子标签
- 但所有标签必须合理的嵌套,绝对不允许交叉嵌套
- 例如:
<a>welcome to <b>www.sohu.org</a></b>
这种写法就是错误的
3、特别提示:在很多时候,说 标签、元素、节点是相同的意思
4、XML 元素命名规则
- 区分大小写,例如,
<P>
和<p>
是两个不同的标记 - 不能以数字开头
- 不能包含空格
- 名称中间不能包含冒号
:
- 如果标签单词需要间隔,建议使用下划线,比如:
<book_title>hello</book_title>
- 创建 语法/students03.xml
<?xml version="1.0" encoding="utf-8" ?>
<!--
解读:
1.区分大小写,例如,<P>和<p>是两个不同的标记。
2.不能以数字开头。
3.不能包含空格。
4.名称中间不能包含冒号(:)。
5.如果标签单词需要间隔,建议使用下划线 比如 <book_title>hello</book_title>
-->
<students>
<student id="100">
<name>jack</name>
<age>10</age>
<gender>男</gender>
<email>jack@sohu.com</email>
<Email>jack2@sohu.com</Email>
<job>java工程师</job>
<book_name>三国</book_name>
</student>
<student id="200">
<name>mary</name>
<age>18</age>
<gender>女</gender>
</student>
</students>
6.5.4 属性
- 属性介绍
<Student ID="100">
<Name>TOM</Name>
</Student>
- 属性值用双引号(“)或单引号(‘)分隔(如果属性值中有’,用"分隔;有”,用’分隔)
- 一个元素可以有多个属性,它的基本格式为:<元素名 属性名=“属性值”>
- 特定的属性名称在同一个元素标记中只能出现一次
- 属性值不能包括& 字符
- 属性应用实例
<?xml version="1.0" encoding="utf-8" ?>
<!--
解读:
1.属性值用双引号(")或单引号(')分隔(如果属性值中有',用"分隔;有",用'分隔)
2.一个元素可以有多个属性,它的基本格式为:<元素名 属性名="属性值">
3.特定的属性名称在同一个元素标记中只能出现一次
4.属性值不能包括& 字符
-->
<students>
<!--
举例:
id='01' 也是正确写法
如果属性值有" 则使用' 包括属性 比如 id="xxx'yyy"
如果属性值有' 则使用" 包括属性 比如 id='xxx"yyy'
属性名在同一个元素标记只能出现一次 <stduent id="01" id="03"> 错误的
属性值不能包括& 字符 比如: <stduent id="0&1"> 是错误的
-->
<student id="100">
<name>jack</name>
<age>10</age>
<gender>男</gender>
</student>
<student id="200">
<name>mary</name>
<age>18</age>
<gender>女</gender>
</student>
</students>
6.5.5 注释
<!--这是一个注释- ->
- 注释内容中不要出现- -;
- 不要把注释放在标记中间;错误写法
<Name <!--the name-->>TOM</Name
- 注释不能嵌套
- 可以在除标记以外的任何地方放注释
6.5.6 CDATA 节!
- 有些内容不想让解析引擎执行
- 而是当作原始内容处理(即当做普通文本),可以使用 CDATA 包括起来
- CDATA 节中的所有字符都会被当作简单文本,而不是 XML 标记
- 语法:
<![CDATA[
这里可以把你输入的字符原样显示,不会解析 xml
]]>
- 可以输入任意字符(除]]>外)
- 不能嵌套
- 应用实例
<?xml version="1.0" encoding="utf-8"?>
<!--
解读:
<![CDATA[
这里可以把你输入的字符原样显示,不会解析 xml
]]>
-->
<students>
<stduent id="01">
<name>tom</name>
<gender>男</gender>
<age>18</age>
<!--
举例说明:
下面是一段js的代码片段. 直接放在<code></code>标签间,语法错误
使用CDATA节来处理即可.
<script data-compress=strip>
function h(obj){
obj.style.behavior='url(#default#homepage)';
var a = obj.setHomePage('//www.baidu.com/');
}
</script>
-->
</stduent>
<stduent id="02">
<name>scott</name>
<gender>女</gender>
<age>17</age>
<code>
<!--如果希望把某些字符串,当做普通文本,使用CDATA包括 -->
<![CDATA[
<script data-compress=strip>
function h(obj){
obj.style.behavior='url(#default#homepage)';
var a = obj.setHomePage('//www.baidu.com/');
}
</script>
]]>
</code>
</stduent>
</students>
6.6 转义字符
- 对于一些单个字符,若想显示其原始样式,也可以使用转义的形式予以处理
转义符 | 符号 |
---|---|
< | < |
> | > |
& | & |
" | " |
' | ’ |
- 应用实例
<?xml version="1.0" encoding="utf-8" ?>
<!--
解读:
对于一些单个字符,若想显示其原始样式,也可以使用转义的形式予以处理
比如 > < & ' ""
-->
<students>
<stduent id="01">
<name>tom</name>
<gender>男</gender>
<age>28</age>
<!--
使用转义字符表示一些特殊字符
<resume>年龄<100 &版权</resume>
-->
<resume>年龄<10 > &</resume>
</stduent>
<stduent id="02">
<name>scott</name>
<gender>女</gender>
<age>17</age>
</stduent>
</students>
6.7 格式正规的 XML 文档-小结
遵循如下规则的 XML 文档称为格式正规的 XML 文档:
- XML 声明语句
<?xml version="1.0" encoding="utf-8"?>
- 必须有且仅有一个根元素
- 标记大小,区分大小写的
- 属性值用引号
- 标记成对
- 空标记关闭
- 元素正确嵌套
6.8 DOM4J
6.8.1 文档: https://dom4j.github.io/javadoc/1.6.1/ .
6.8.2 本地文档: dom4j-1.6.1\docs\index.html
6.8.3 XML 解析技术原理
- 不管是 html 文件还是 xml 文件它们都是标记型文档,都可以使用 w3c 组织制定的 dom 技术来解析
- . document 对象表示的是整个文档,可以是 html 文档,也可以是 xml 文档
6.8.4 XML 解析技术介绍
- 早期 JDK 为我们提供了两种 xml 解析技术 DOM 和 Sax 简介
- dom 解析技术是 W3C 组织制定的,而所有的编程语言都对这个解析技术使用了自己语言的特点进行实现。 Java 对 dom 技术解析也做了实现
- sun 公司在 JDK5 版本对 dom 解析技术进行升级:SAX( Simple API for XML ) SAX解析,它是以类似事件机制通过回调告诉用户当前正在解析的内容。 是一行一行的读取 xml 文件进行解析的。不会创建大量的 dom 对象。 所以它在解析 xml 的时候,在性能上优于 Dom 解析
- 这两种技术已经过时,知道有这两种技术即可
- 第三方的 XML 解析技术
- jdom 在 dom 基础上进行了封装
- dom4j 又对 jdom 进行了封装
- pull 主要用在 Android 手机开发,是在跟 sax 非常类似都是事件机制解析 xml 文件
6.8.5 DOM4J 介绍
- Dom4j 是一个简单、灵活的开放源代码的库(用于解析/处理 XML 文件) Dom4j 是由早期开发 JDOM 的人分离出来而后独立开发的
- 与 JDOM 不同的是,dom4j 使用接口和抽象基类,虽然 Dom4j 的 API 相对要复杂一些,但它提供了比 JDOM 更好的灵活性
- Dom4j 是一个非常优秀的 Java XML API,具有性能优异、功能强大和极易使用的特点。现在很多软件采用的Dom4j
- 使用 Dom4j 开发,需下载 dom4j 相应的 jar 文件
6.8.6 解压 zip 文档,参考 DOM4J 文档
- 下载地址(自己下载):https://dom4j.github.io.
6.8.7 DOM4j 中,获得 Document 对象的方式有三种
- 开发 dom4j 要先导入 dom4j 的jar包
- 读取 XML 文件,获得 document 对象
SAXReader reader = new SAXReader(); //创建一个解析器
Document document = reader.read(new File("src/input.xml")); //获得 XML Document
- 解析 XML 形式的文本,得到 document 对象.
String text = "<members></members>";
Document document = DocumentHelper.parseText(text);
- 主动创建 document 对象.
Document document = DocumentHelper.createDocument(); //创建根节点
Element root = document.addElement("members");
6.8.8 DOM4J 应用实例
- 使用 DOM4J 对 students.xml 文件进行增删改查
- 重点学习查询(遍历和指定查询)
- xml增删改使用少,作为扩展,给出案例
- 引入 dom4j 的依赖的 jar 包
- 创建E:\javaweb_project\xml\src\students.xml文件
<?xml version="1.0" encoding="utf-8"?>
<students>
<student id="01">
<name>小龙女</name>
<gender>女</gender>
<age>19</age>
<resume>古墓派掌门人</resume>
</student>
<student id="02">
<name>欧阳锋</name>
<gender>男</gender>
<age>21</age>
<resume>白驼山,蛤蟆神功</resume>
</student>
</students>
- 创建E:\javaweb_project\xml\src\Dom4j_.java,演示 Dom4j 对 xml 文件的增删改查/遍历
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
import org.junit.jupiter.api.Test;
import java.io.File;
import java.io.FileOutputStream;
import java.util.List;
/**
* @Author: 谢家升
* @Date: 2022/2/15-02-15-8:25
* @Version: 1.0
*/
public class Dom4j_ {
/**
* 演示如何加载xml文件
*/
@Test
public void loadXML() throws DocumentException {
//得到一个解析器
SAXReader reader = new SAXReader();
//代码技巧->debug 看看document对象的属性
//分析了document对象的底层结构
Document document = reader.read(new File("src/students.xml"));
System.out.println(document);
}
/**
* 遍历所有的student信息
*/
@Test
public void listStus() throws DocumentException {
//得到一个解析器
SAXReader reader = new SAXReader();
//代码技巧->debug 看看document对象的属性
//分析了document对象的底层结构
Document document = reader.read(new File("src/students.xml"));
//1. 得到rootElement, 你是OOP
Element rootElement = document.getRootElement();
//2. 得到rootElement的student Elements
List<Element> students = rootElement.elements("student");
//System.out.println(student.size());//2
for (Element student : students) {//element就是Student元素/节点
//获取Student元素 的name Element
Element name = student.element("name");
Element age = student.element("age");
Element resume = student.element("resume");
Element gender = student.element("gender");
System.out.println("学生信息= " + name.getText() + " " + age.getText() +
" " + resume.getText() + " " + gender.getText());
}
}
/**
* 指定读取第一个学生的信息 就是 dom4j+xpath
*/
@Test
public void readOne() throws DocumentException {
//得到一个解析器
SAXReader reader = new SAXReader();
//代码技巧->debug 看看document对象的属性
//分析了document对象的底层结构
Document document = reader.read(new File("src/students.xml"));
//1. 得到rootElement, 你是OOP
Element rootElement = document.getRootElement();
//2. 获取第一个学生
Element student = (Element) rootElement.elements("student").get(1);
//3. 输出该信息
System.out.println("该学生的信息= " + student.element("name").getText() + " " +
student.element("age").getText() + " " + student.element("resume").getText() +
student.element("gender").getText());
//4. 获取student元素的属性
System.out.println("id= " + student.attributeValue("id"));
}
/**
* 加元素(要求: 添加一个学生到xml中) [不要求,使用少,了解]
* @throws Exception
*/
@Test
public void add() throws Exception {
//1.得到解析器
SAXReader saxReader = new SAXReader();
//2.指定解析哪个xml文件
Document document = saxReader.read(new File("src/students.xml"));
//首先我们来创建一个学生节点对象
Element newStu = DocumentHelper.createElement("student");
Element newStu_name = DocumentHelper.createElement("name");
//如何给元素添加属性
newStu.addAttribute("id", "04");
newStu_name.setText("宋江");
//创建age元素
Element newStu_age = DocumentHelper.createElement("age");
newStu_age.setText("23");
//创建resume元素
Element newStu_intro = DocumentHelper.createElement("resume");
newStu_intro.setText("梁山老大");
//把三个子元素(节点)加到 newStu下
newStu.add(newStu_name);
newStu.add(newStu_age);
newStu.add(newStu_intro);
//再把newStu节点加到根元素
document.getRootElement().add(newStu);
//直接输出会出现中文乱码:
OutputFormat output = OutputFormat.createPrettyPrint();
output.setEncoding("utf-8");//输出的编码utf-8
//把我们的xml文件更新
// lets write to a file
//new FileOutputStream(new File("src/myClass.xml"))
//使用到io编程 FileOutputStream 就是文件字节输出流
XMLWriter writer = new XMLWriter(
new FileOutputStream(new File("src/students.xml")), output);
writer.write(document);
writer.close();
}
/**
* //删除元素(要求:删除第一个学生) 使用少,了解
* @throws Exception
*/
@Test
public void del() throws Exception {
//1.得到解析器
SAXReader saxReader = new SAXReader();
//2.指定解析哪个xml文件
Document document = saxReader.read(new File("src/students.xml"));
//找到该元素第一个学生
Element stu = (Element) document.getRootElement().elements("student").get(2);
//删除元素
stu.getParent().remove(stu);
// //删除元素的某个属性
// stu.remove(stu.attribute("id"));
//更新xml
//直接输出会出现中文乱码:
OutputFormat output = OutputFormat.createPrettyPrint();
output.setEncoding("utf-8");//输出的编码utf-8
//把我们的xml文件更新
XMLWriter writer = new XMLWriter(
new FileOutputStream(new File("src/students.xml")), output);
writer.write(document);
writer.close();
System.out.println("删除成功~");
}
/**
* //更新元素(要求把所有学生的年龄+3) 使用少,了解
* @throws Exception
*/
@Test
public void update() throws Exception {
//1.得到解析器
SAXReader saxReader = new SAXReader();
//2.指定解析哪个xml文件
Document document = saxReader.read(new File("src/students.xml"));
//得到所有学生的年龄
List<Element> students = document.getRootElement().elements("student");
//遍历, 所有的学生元素的age+3
for (Element student : students) {
//取出年龄
Element age = student.element("age");
age.setText((Integer.parseInt(age.getText()) + 3) + "");
}
//更新
//直接输出会出现中文乱码:
OutputFormat output = OutputFormat.createPrettyPrint();
output.setEncoding("utf-8");//输出的编码utf-8
//把我们的xml文件更新
XMLWriter writer = new XMLWriter(
new FileOutputStream(new File("src/students.xml")), output);
writer.write(document);
writer.close();
System.out.println("更新成功~");
}
}
6.9 课后作业
- 根据给出的 books.xml,创建对应的 Book 对象(有几个创建几个)
<?xml version="1.0" encoding="UTF-8" ?>
<books>
<book id="100">
<name>西游记</name>
<author>吴承恩</author>
<price>80</price>
</book>
<book id="200">
<name>三国</name>
<author>罗贯中</author>
<price>100</price>
</book>
</books>
-
思路分析 + 代码实现
(1)遍历所有的 book 元素->得到每个 book 元素的信息
(2)创建一个 Book 类,根据 book 元素信息来创建 book 对象
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import java.io.File;
import java.util.List;
/**
* @Author: 谢家升
* @Date: 2022/2/15-02-15-10:38
* @Version: 1.0
*/
public class Homework {
public static void main(String[] args) throws DocumentException {
//1.得到一个解析器
SAXReader reader = new SAXReader();
//代码技巧--->debug 看看document对象的属性
//2.指定解析哪个XML文件
Document document = reader.read(new File("src/book.xml"));
//3.遍历所有的book元素
List<Element> books = document.getRootElement().elements("book");
for (Element book : books) {
//取出book元素所有信息
Element name = book.element("name");
Element author = book.element("author");
Element price = book.element("price");
String id = book.attributeValue("id");
//创建成book对象
Book book1 = new Book();
book1.setId(Integer.parseInt(id));
book1.setName(name.getText());
book1.setAuthor(author.getText());
book1.setPrice(Double.parseDouble(price.getText()));
System.out.println("book1对象信息= " + book1);
}
}
}