一.XML基本介绍
XML(Extensible Markup Language)是一种标记语言,它允许用户定义自己的标签(或称为“元素”)来组织数据。XML被设计用来传输和存储数据,而不仅仅是展示数据。它是一种纯文本格式,意味着它可以用任何文本编辑器创建和编辑,同时也易于被计算机程序读取和处理。
1.1 XML的特点:
XML的主要特点包括:
- 可扩展性:XML允许用户根据需要定义自己的标签,这意味着它可以用于各种应用程序中,从简单的数据交换到复杂的业务逻辑。
- 自描述性:XML文档包含有关其内容的元数据(通过标签),这使得即使没有外部描述文档(如DTD或Schema),也能理解XML文档的结构。
- 结构化:XML文档通过嵌套标签来组织数据,形成树状结构,这种结构使得数据易于管理和访问。
- 跨平台性:由于XML是纯文本格式,因此它可以在任何操作系统和平台上使用,无需进行特殊转换。
- 多种用途:XML广泛应用于数据交换、配置文件、网络传输、软件文档等领域.
1.2 XML能做什么?
二.XML基本语法
1.1 基本语法
1.XML中必须进行文档声明
version 版本信息
endcoding 编码
2.xml的文档声明必须写在第一行
3.XML 中的元素标签 命名规则
1.标签定义 不能使用空格 或者 冒号
2.xml 标签名称 区分大小写
4.XML中有且只有一共根元素
5.元素体 可以是文本 或者 还是一个标签
6.属性是元素的一部分 只能出现在元素的开始标签中
属性值必须使用单引号或者双引号包裹
一个标签可以定义多个属性
1.2 自定义XML描述数据
<?xml version="1.0" encoding="UTF-8" ?>
<employees>
<employee eid="2">
<ename>林黛玉</ename>
<age>20</age>
<sex>女</sex>
<salary>5000</salary>
<empdate>2010-01-01</empdate>
</employee>
<employees>
<employee eid="3">
<ename>杜甫</ename>
<age>20</age>
<sex>男</sex>
<salary>5000</salary>
<empdate>2010-01-01</empdate>
</employee>
</employees>
1.3 XML约束
1.4 DTD约束
DTD(Document Type Definition),文档类型定义,用来约束XML文档。规定XML文档中元素的名 称,子元素的名称及顺序,元素的属性等
开发中,我们不会自己编写DTD约束文档
常情况我们都是通过框架提供的DTD约束文档,编写对应的XML文档。常见框架使用DTD约束有: Struts2、hibernate等。
DTD约束代码内容解析:
<!ELEMENT students (student+) >
<!ELEMENT student (name,age,sex)>
<!ELEMENT name (#PCDATA)>
<!ELEMENT age (#PCDATA)>
<!ELEMENT sex (#PCDATA)>
<!ATTLIST student number ID #REQUIRED>
<!--
ELEMENT: 用来定义元素
students (student+) : 代表根元素 必须是 <students>
student+ : 根标签中至少有一个 student子元素, + 代表至少一个
#PCDATA: 是普通文本内容
student (name,age,sex): student 标签中包含的子元素,按顺序出现
ATTLIST: 用来定义属性
student number ID #REQUIRED
student子元素中 有一个ID属性叫做 number,是必须填写的
ID: 唯一 值只能是字母或者下划线开头-->
1.5 引入DTD约束
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE sudents SYSTEM "student.dtd">
<students>
<student number="s1">
<name>长海</name>
<age>20</age>
<sex>男</sex>
</student>
<student number="s2">
<name>狗剩</name>
<age>21</age>
<sex>男</sex>
</student>
</students>
1.6 Schema约束
- Schema是新的XML文档约束, 比DTD强大很多,是DTD 替代者;
- Schema本身也是XML文档,但Schema文档的扩展名为xsd,而不是xml。
- Schema 功能更强大,内置多种简单和复杂的数据类型
- Schema 支持命名空间 (一个XML中可以引入多个约束文档
命名空间:指的是一个环境,所用的标签来自于哪个环境定义的。
1.7 引入Schema约束
<?xml version="1.0" encoding="UTF-8" ?>
<students
xmlns="https://www.bilibili.com/xml"
xmlns:xsi="http://www.w3.org/2001/XMLSchema"
xsi:schemaLocation="https://www.bilibili.com/xml student.xsd"
>
<student number="hehe_1234">
<name>张三</name>
<age>10</age>
<sex>male</sex>
</student>
<student number="hehe_4567">
<name>张三</name>
<age>20</age>
<sex>male</sex>
</student>
</students>
三.XML解析
1.1 XML解析概述
解析XML文档是读取XML数据并提取所需信息的过程。这个过程可以通过不同的方式完成,主要取决于你的需求和所使用的编程语言。 XML解析主要分为两种类型:
-
DOM(Document Object Model)解析:
- DOM解析器将整个XML文档加载到内存中,并构建成一个树状结构(DOM树),其中的每个节点都对应XML文档中的一个元素、属性或文本等。
- 优点:易于理解和使用,因为整个文档都被加载到内存中,所以可以通过编程方式访问文档的任何部分。
- 缺点:对于大型文档,可能会消耗大量内存。
-
SAX(Simple API for XML)解析:
- SAX解析器是一个基于事件的解析器,它边读取XML文档边解析,占用内存少。
- 当解析器遇到XML文档中的特定元素时,它会触发(或“抛出”)事件(如开始元素、结束元素、文本等),并允许应用程序对这些事件作出响应。
- 优点:内存占用低,适用于处理大型文件。
- 缺点:因为数据是按需读取的,所以可能难以访问文档中的随机位置。
1.2 DOM解析和SAX解析的区别:
DOM解析和SAX解析是XML文档解析的两种主要方式,它们在处理XML文档时有显著的区别。以下是DOM解析和SAX解析的主要区别:
1. 解析方式
- DOM解析:DOM(Document Object Model)解析器会将整个XML文档加载到内存中,并构建一个树状结构(DOM树)。这个树状结构中的每个节点都对应XML文档中的一个元素、属性或文本等。开发者可以通过编程方式遍历这个DOM树,以访问或修改文档中的数据。
- SAX解析:SAX(Simple API for XML)解析器是一种基于事件的解析器。它边读取XML文档边解析,不会将整个文档加载到内存中。当SAX解析器遇到XML文档中的特定元素时,它会触发(或“抛出”)事件(如开始元素、结束元素、文本等),并允许应用程序对这些事件作出响应。
2. 内存占用
- DOM解析:由于DOM解析器将整个文档加载到内存中,因此它可能会消耗大量的内存,尤其是当处理大型XML文档时。
- SAX解析:SAX解析器只占用很少的内存,因为它不会将整个文档加载到内存中。它只处理当前读取的部分,并在处理完成后立即释放资源。
3. 访问和修改能力
- DOM解析:由于DOM树在内存中构建,因此开发者可以轻松地访问和修改文档中的任何部分。这使得DOM解析器非常适合需要频繁访问和修改XML数据的场景。
- SAX解析:SAX解析器不提供对文档的随机访问能力。它只能按顺序读取文档,并在读取过程中触发事件。因此,SAX解析器不适合需要修改XML数据的场景,而更适合只需要读取数据的场景。
4. 灵活性
- DOM解析:DOM解析器提供了丰富的API来访问和修改XML文档,使得开发者可以灵活地处理XML数据。
- SAX解析:SAX解析器的灵活性相对较低,因为它主要依赖于事件处理机制。开发者需要编写事件处理器来响应SAX解析器触发的事件,并根据需要处理数据。
5. 适用场景
- DOM解析:适用于需要频繁访问和修改XML数据的场景,以及当内存资源相对充足时。
- SAX解析:适用于只需要读取XML数据,且内存资源有限的场景。特别是当处理大型XML文档时,SAX解析器通常是更好的选择。
1.3 常见的XML解析器
**解析器:就是根据不同的解析方式提供的具体实现。有的解析器操作过于繁琐,为了方便开发人员, 有提供易于操作的解析开发包 **
JAXP:sun公司提供的解析器,支持DOM和SAX两种思想 DOM4J:一款非常优秀的解析器.
Dom4j是一个易用的、开源的库,用于XML,XPath和XSLT。 它应用于Java平台,采用了Java集合框架并完全支持DOM,SAX和JAXP。
Jsoup:jsoup 是一款Java 的HTML解析器 ,也可以解析XML
PULL:Android内置的XML解析方式,类似SAX。
1.4 Dom4j解析器介绍
编写xsd文档 并且引用Schema约束
<?xml version="1.0" encoding="UTF-8" ?>
<users
xmlns="http://www.lagou.com/xml"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.lagou.com/xml user.xsd"
>
<user id="123">
<name>张百万</name>
<age>25</age>
<hobby>抽烟</hobby>
</user>
<user id="002">
<name>于谦</name>
<age>25</age>
<hobby>烫头</hobby>
</user>
Dom4j解析XML代码:
package com.xml.xml01.xml03;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import java.util.List;
public class TestDOM4j {
public static void main(String[] args) {
try {
new TestDOM4j().test1();
} catch (DocumentException e) {
throw new RuntimeException(e);
}
}
//获取XML文件中的所有元素
public void test1() throws DocumentException {
//1.获取XML解析对象
SAXReader reader = new SAXReader();
//2.解析XML 获取文档对象 document
Document document = reader.read("C:\Users\16925\IdeaProjects\xml_task03\xml_task031\src\com\xml\xml01\xml03\user.xml");
//3.获取根元素
Element rootElement = document.getRootElement();
//获取根元素名称
System.out.println(rootElement.getName());
//获取根元素下的标签
List<Element> elements = rootElement.elements();
for (Element element : elements) {
System.out.println("根标签下的子节点:"+element.getName());
List<Element> elements1 = element.elements();
for (Element element1 : elements1) {
System.out.println("user标签下的子节点"+element1.getName());
}
break;
}
}
//获取XML中标签的文本信息和属性信息
public void test2() throws DocumentException {
//1.获取解析XML的SAXReader
SAXReader reader = new SAXReader();
//2.获取文档对象
Document document = reader.read("C:\Users\16925\IdeaProjects\xml_task03\xml_task031\src\com\xml\xml01\xml03\user.xml");
//3.获取根节点
Element rootElement = document.getRootElement();
//4.获取子节点 user
List<Element> elements= rootElement.elements();
//5.获取集合中的第一个子节点
Element user = elements.get(0);
//6.获取节点中的文本信息4
String id = user.attributeValue("id");
String name = user.attributeValue("name");
String age = user.attributeValue("age");
String hobby = user.element("hobby").getText();
//打印
System.out.println(id+""+name+""+age+""+ hobby);
}
}
1.5 XPath
XPath 是一门在 XML 文档中查找信息的语言。 可以是使用xpath查找xml中的内容。
XPath 的好处
由于DOM4J在解析XML时只能一层一层解析,所以当XML文件层数过多时使用会很不方便,结合 XPATH就可以直接获取到某个元素
使用dom4j支持xpath的操作的几种主要形式
常用方法:
(一).Xpath语法获取单个节点信息
public void test1() throws DocumentException {
/**
* 1使用selectSingleNode() 方法 查询指定节点信息
*/
//1.创建XML解析对象
SAXReader reader = new SAXReader();
//2.解析XML 获取 文档对象
Document document = reader.read("C:\Users\16925\IdeaProjects\xml_task03\xml_task031\src\com\xml\xml01\xml04\book.xml");
//3.通过selectSingLeNode() 方法获取name节点
Node node1 = document.selectSingleNode("/bookstore/book/name");
System.out.println("节点的名称:"+node1.getName());
System.out.println("书名:"+node1.getText());
//4.获取第二本的书名
Node node2 = document.selectSingleNode("/bookstore/book[2]/name");
System.out.println("第二本书的书名:"+node2.getText());
}
(二).Xpath语法获取属性值
/**
* 2使用 selectSIngLeNode() 方法 获取属性值 或者 通过属性值获取到节点的信息
*/
public void test2() throws DocumentException {
//1.创建解析器对象
SAXReader sr = new SAXReader();
//2.获取文档对象
Document document = sr.read("C:\Users\16925\IdeaProjects\xml_task03\xml_task031\src\com\xml\xml01\xml04\book.xml");
//3.获取第一个book节点的 id属性的值
Node node1 = document.selectSingleNode("/bookstore/book/attribute::id");
System.out.println("第一个book的id值为: " + node1.getText());
//4.获取最后一个book节点的 id属性的值
Node node2 = document.selectSingleNode("/bookstore/book[last()]/attribute::id");
System.out.println("最后一个book节点的id值为: " + node2.getText());
//5.获取id属性值为 book2的 书名
Node node3 = document.selectSingleNode("/bookstore/book[@id='book2']");
String name = node3.selectSingleNode("name").getText();
System.out.println("id为book2的书名是: " + name);
}
(三).Xpath语法获取多个节点信息
public void test3() throws DocumentException {
//1.创建解析器对象
SAXReader sr = new SAXReader();
//2.获取文档对象
Document document = sr.read("C:\Users\16925\IdeaProjects\xml_task03\xml_task031\src\com\xml\xml01\xml04\book.xml");
//3.获取所有节点,打印节点名
List<Node> list = document.selectNodes("//*");
for (Node node : list) {
System.out.println("节点名: " + node.getName());
}
//4.获取所有的书名
List<Node> names = document.selectNodes("//name");
for (Node name : names) {
System.out.println(name.getText());
}
//5.获取指定 id值为book1的节点的所有 内容
List<Node> book1 =
document.selectNodes("/bookstore/book[@id='book1']//*");
for (Node node : book1) {
System.out.println(node.getName()+" = " + node.getText());
}
}
四.配置式JDBCUtils(JDBC自定义XML)
创建自定义xml 文件, 保存 数据库连接信息
<?xml version="1.0" encoding="UTF-8" ?>
<jdbc>
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/db5?characterEncoding=UTF-8</property>
<property name="user">root</property>
<property name="password">123123</property>
</jdbc>
编写工具类:
package com.xml.xml01.xml05;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class JDBCUtills {
//1.定义字符串变量 保存连接信息
public static String DRIVERNAME;
public static String URL;
public static String USER;
public static String PASSWORD;
//2.静态代码块
static {
//使用XPath语法 对XML中的数据进行读取
SAXReader reader = new SAXReader();
try {
Document document = reader.read("C:\Users\16925\IdeaProjects\xml_task03\xml_task031\src\com\xml\xml01\xml05\jdbc-config.xml");
//1.获取驱动名称
Node driver = document.selectSingleNode("jdbc/property[@name'driverClass']");
DRIVERNAME = driver.getText();
//2.获取URL
Node url = document.selectSingleNode("/jdbc/property[@name='jdbcUrl']");
URL = url.getText();
//3.获取用户名
Node user = document.selectSingleNode("/jdbc/property[@name='user']");
USER = user.getText();
//4.获取密码
Node password = document.selectSingleNode("/jdbc/property[@name='password']");
PASSWORD = password.getText();
//注册驱动
Class.forName(DRIVERNAME);
} catch (Exception e) {
throw new RuntimeException(e);
//
}
}
//获取连接
public static Connection getConnection(){
try {
Connection connection = DriverManager.getConnection(URL, USER, PASSWORD);
return connection;
} catch (SQLException e) {
throw new RuntimeException(e);
return null;
}
}
}
测试工具类:
package com.xml.xml01.xml05;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class TestJDBC {
//查询所有员工信息
public static void main(String[] args) throws SQLException {
//1.获取连接
Connection connection = JDBCUtills.getConnection();
//2.获取Statement对象
Statement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery("select * from employee");
//3.处理结果集
while (resultSet.next()){
String name = resultSet.getString("ename");
System.out.println("员工的姓名:"+name);
}
//4.关闭资源
resultSet.close();
statement.close();
connection.close();
}
}