XML
1. XML基本介绍
1.1 概述
XML
即可扩展标记语言(
Extensible Markup Language
)
(1)W3C
在
1998
年
2
月发布
1.0
版本,
2004
年
2
月又发布
1.1
版本,但因为
1.1
版本不能向下兼容
1.0
版本,所以1.1
没有人用。同时,在
2004
年
2
月
W3C
又发布了
1.0
版本的第三版。我们要学习的还是1.0版本
!
特点
(1)可扩展的
,
标签都是自定义的
(2)语法十分严格
1.2 XML的作用
XML
能做什么
?
2. XML的语法
2.1 XML文档声明格式
文档声明必须为结束;
文档声明必写在第一行;
1)
语法格式
<?xml version="1.0" encoding="UTF-8"?>
2)
属性说明
:
versioin
:指定
XML
文档版本。必须属性,因为我们不会选择
1.1
,只会选择
1.0
;
encoding
:指定当前文档的编码。可选属性,默认值是
utf-8
;
2.2 元素
Element
元素
:
是
XML
文档中最重要的组成部分
元素的命名规则
1.
不能使用空格,不能使用冒号
2. xml
标签名称区分大小写
3. XML
必须有且只有一个根元素
语法格式
:
<users><users>
1) XML
必须有且只有一个根元素,它是所有其他元素的父元素,比如以下实例中
users
就是根元素:
<?xml version="1.0" encoding="utf-8" ?>
<users>
</users>
2)
普通元素的结构开始标签、元素体、结束标签组成。
<hello> 大家好 </hello>
3)
元素体:元素体可以是元素,也可以是文本
<hello>
<a>你好</a>
</hello>
4)
空元素:空元素只有开始标签,而没有结束标签,但元素必须自己闭合
<close/>
2.3 属性
<bean id="" class=""> </bean>
1.
属性是元素的一部分,它必须出现在元素的开始标签中
2.
属性的定义格式:属性名
=
属性值,其中属性值必须使用单引或双引
3.
一个元素可以有
0~N
个属性,但一个元素中不能出现同名属性
4.
属性名不能使用空格、冒号等特殊字符,且必须以字母开头
2.4 注释
XML
的注释,以
“ <!--”
开始,以
“--> ”
结束。注释内容会被
XML
解析器忽略!
2.5 使用XML 描述数据表中的数据
<?xml version="1.0" encoding="UTF-8" ?>
<employees>
<employee eid="2">
<ename>林黛玉</ename>
<age>20</age>
<sex>女</sex>
<salary>5000</salary>
<empdate>2019-03-14</empdate>
</employee>
<employee eid="3">
<ename>杜甫</ename>
<age>40</age>
<sex>男</sex>
<salary>15000</salary>
<empdate>2010-01-01</empdate>
</employee>
</employees>
3. XML约束
(1)在
XML
技术里,可以编写一个文档来约束一个
XML
文档的书写规范,这称之为
XML
约束。
(2)常见的
xml
约束:
DTD
Schema
(3)作为程序员只要掌握两点
会阅读
会引入
不用自己编写
3.1 DTD约束
DTD
(
Document Type Definition
),文档类型定义,用来约束
XML
文档。规定
XML
文档中元素的名称,子元素的名称及顺序,元素的属性等。
3.1.1 编写DTD
(1)开发中,我们不会自己编写
DTD
约束文档
(2)常情况我们都是通过框架提供的
DTD
约束文档,编写对应的
XML
文档。常见框架使用
DTD
约束有:
Struts2
、
hibernate
等。
创建约束文件
student.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子元素, + 代表至少一个
student (name,age,sex): student 标签中包含的子元素,按顺序出现
#PCDATA: 是普通文本内容
ATTLIST: 用来定义属性
student number ID #REQUIRED
student子元素中 有一个ID属性叫做 number,是必须填写的
ID: 唯一 值只能是字母或者下划线开头
-->
3.1.2 引入DTD
引入
dtd
文档到
xml
文档中
,
两种方式
(1)内部
dtd
:将约束规则定义在
xml
文档中
(2)外部
dtd
:将约束的规则定义在外部的
dtd
文件中
本地:
网络:
student.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE students SYSTEM "student.dtd">
<students>
<student number="s1">
<name>小斌</name>
<age>22</age>
<sex>男</sex>
</student>
<student number="s2">
<name>广坤</name>
<age>55</age>
<sex>男</sex>
</student>
</students>
3.2 Schema约束
3.2.1 什么是Schema
1. Schema
是新的
XML
文档约束
,
比
DTD
强大很多,是
DTD
替代者;
2. Schema
本身也是
XML
文档,但
Schema
文档的扩展名为
xsd
,而不是
xml
。
3. Schema
功能更强大,内置多种简单和复杂的数据类型
4. Schema
支持命名空间
(
一个
XML
中可以引入多个约束文档
)
3.2.2 Schema约束示例
student.xsd
<?xml version="1.0"?>
<xsd:schema xmlns="http://www.lagou.com/xml"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.lagou.com/xml"
elementFormDefault="qualified">
<xsd:element name="students" type="studentsType"/>
<xsd:complexType name="studentsType">
<xsd:sequence>
<xsd:element name="student" type="studentType" minOccurs="0"
maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="studentType">
<xsd:sequence>
<xsd:element name="name" type="xsd:string"/>
<xsd:element name="age" type="ageType" />
<xsd:element name="sex" type="sexType" />
</xsd:sequence>
<xsd:attribute name="number" type="numberType" use="required"/>
</xsd:complexType>
<xsd:simpleType name="sexType">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="male"/>
<xsd:enumeration value="female"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="ageType">
<xsd:restriction base="xsd:integer">
<xsd:minInclusive value="0"/>
<xsd:maxInclusive value="200"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="numberType">
<xsd:restriction base="xsd:string">
<xsd:pattern value="hehe_\d{4}"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:schema>
Xml Schema
的根元素:
3.2.3 XML引入Schema约束
xml
中引入
schema
约束的步骤:
1)
查看
schema
文档,找到根元素,在
xml
中写出来
<?xml version="1.0" encoding="UTF-8" ?>
<students>
</students>
2)
根元素来自哪个命名空间。使用
xmlns
指令来声明
<?xml version="1.0" encoding="UTF-8" ?>
<students
xmlns="http://www.lagou.com/xml"
>
</students>
3)
引入
w3c
的标准命名空间
,
复制即可
<?xml version="1.0" encoding="UTF-8" ?>
<students
xmlns="http://www.lagou.com/xml"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
>
</students>
4)
引入的命名空间跟哪个
xsd
文件对应?
使用
schemaLocation
来指定:两个取值:第一个为命名空间 第二个为
xsd
文件的路径
<?xml version="1.0" encoding="UTF-8" ?>
<students
xmlns="http://www.lagou.com/xml"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.lagou.com/xml student.xsd"
>
</students>
5)
命名空间
指的是一个环境
,
所用的标签来自于哪个环境定义的
6) student.xml
<?xml version="1.0" encoding="UTF-8" ?>
<students
xmlns="http://www.lagou.com/xml"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.lagou.com/xml student.xsd"
>
<student number="hehe_1234">
<name>张百万</name>
<age>25</age>
<sex>female</sex>
</student>
<student number="hehe_0000">
<name>小斌</name>
<age>20</age>
<sex>male</sex>
</student>
</students>
4. XML 解析
4.1 解析概述
当将数据存储在
XML
后,我们就希望通过程序获得
XML
的内容。如果我们使用
Java
基础所学习的
IO
知识是可以完成的,不过你需要非常繁琐的操作才可以完成,且开发中会遇到不同问题(只读、读写)。人们为不同问题提供不同的解析方式,并提交对应的解析器,方便开发人员操作XML
。
4.2 XML解析方式
开发中比较常见的解析方式有两种,如下:
(1)DOM
:要求解析器把整个
XML
文档装载到内存,并解析成一个
Document
对象。
优点:元素与元素之间保留结构关系,故可以进行增删改查操作。
缺点:
XML
文档过大,可能出现内存溢出显现。
(2) SAX
:是一种速度更快,更有效的方法。它逐行扫描文档,一边扫描一边解析。并以事件驱 动的方式进行具体解析,每执行一行,都将触发对应的事件。(了解)
优点:占用内存少 处理速度快,可以处理大文件
缺点:只能读,逐行后将释放资源。
4.3 XML常见的解析器
解析器:就是根据不同的解析方式提供的具体实现。有的解析器操作过于繁琐,为了方便开发人员,有提供易于操作的解析开发包
(1)JAXP
:
sun
公司提供的解析器,支持
DOM
和
SAX
两种思想
(2)DOM4J
:一款非常优秀的解析器
, Dom4j
是一个易用的、开源的库,用于
XML
,
XPath
和
XSLT
。它应用于Java
平台,采用了
Java
集合框架并完全支持
DOM
,
SAX
和
JAXP
。
(3)Jsoup
:
jsoup
是一款
Java
的
HTML
解析器
,
也可以解析
XML
(4)PULL
:
Android
内置的
XML
解析方式,类似
SAX
。
4.4 dom4j 的使用
4.4.1 导入JAR包
4.4.2 API介绍
使用核心类
SaxReader
加载
xml
文档获得
Document
,通过
Document
对象获得文档的根元素,然后就可以操作了
常用
API
如下:
SaxReader
对象
read(…)
加载执行
xml
文档
Document
对象
getRootElement()
获得根元素
Element
对象
elements(…)
获得指定名称的所有子元素。可以不指定名称
element(…)
获得指定名称的第一个子元素。可以不指定名称
getName()
获得当前元素的元素名
attributeValue(…)
获得指定属性名的属性值
elementText(…)
获得指定名称子元素的文本值
getText()
获得当前元素的文本内容
4.4.3 准备xml文件
编写
user.xsd schema
约束
<?xml version="1.0" encoding="UTF-8" ?>
<xsd:schema xmlns="http://www.lagou.com/xml"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.lagou.com/xml"
elementFormDefault="qualified">
<xsd:element name="users" type="usersType"/>
<xsd:complexType name="usersType">
<xsd:sequence>
<xsd:element name="user" type="userType" minOccurs="0"
maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="userType">
<xsd:sequence>
<xsd:element name="name" type="xsd:string"/>
<xsd:element name="age" type="ageType" />
<xsd:element name="hobby" type="hobbyType" />
</xsd:sequence>
<xsd:attribute name="id" type="numberType" use="required"/>
</xsd:complexType>
<xsd:simpleType name="ageType">
<xsd:restriction base="xsd:integer">
<xsd:minInclusive value="0"/>
<xsd:maxInclusive value="100"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="hobbyType">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="抽烟"/>
<xsd:enumeration value="喝酒"/>
<xsd:enumeration value="烫头"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="numberType">
<xsd:restriction base="xsd:string">
<xsd:pattern value="\d"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:schema>
编写
user.xml
引入约束
<?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="1">
<name>张百万</name>
<age>20</age>
<hobby>抽烟</hobby>
</user>
<user id="2">
<name>于谦</name>
<age>50</age>
<hobby>喝酒</hobby>
</user>
<user id="3">
<name>刘能</name>
<age>40</age>
<hobby>烫头</hobby>
</user>
</users>
4.4.4 读取XML
public class TestDOM4j {
//获取XML文件中的 所有的元素名称(标签)
@Test
public void test1() throws DocumentException {
//1.获取XML解析对象
SAXReader reader = new SAXReader();
//2.解析XML 获取 文档对象 document
Document document =
reader.read("H:\\jdbc_work\\xml_task03\\src\\com\\lagou\\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> eList = element.elements();
for (Element e : eList) {
System.out.println("user标签下的子节点" + e.getName());
}
break;
}
}
/**
* 获取具体的节点内容 获取张百万的所有信息
*/
@Test
public void test2() throws DocumentException {
//1.创建XML文档解析对象
SAXReader sr = new SAXReader();
//2.读取XML获取到document对象
Document document = sr.read("src\\com\\lagou\\xml02\\user.xml");
//3.获取根节点
Element rootElement = document.getRootElement();
//4.得到当前节点的 所有子节点
List<Element> elements = rootElement.elements();
//5.获取第一个子节点
Element user = elements.get(0);
//6.获取所有信息
String id = user.attributeValue("id");
String name = user.elementText("name");
String age = user.elementText("age");
//使用getText获取当前元素的文本内容
String hobby = user.element("hobby").getText();
//打印
System.out.println(id+" " + name +" " + age +" " + hobby);
}
}
4.5 xpath方式读取xml
4.5.1 xpath介绍
XPath
是一门在
XML
文档中查找信息的
语言
。 可以是使用
xpath
查找
xml
中的内容。
XPath
的好处
由于
DOM4J
在解析
XML
时只能一层一层解析,所以当
XML
文件层数过多时使用会很不方便,结合XPATH就可以直接获取到某个元素
1
)需要再导入
jaxen-1.1-beta-6.jar
4.5.2 XPath基本语法介绍
使用
dom4j
支持
xpath
的操作的几种主要形式
4.5.3 API介绍
2)
常用方法:
selectSingleNode(query):
查找和
XPath
查询匹配的一个节点。
参数是
Xpath
查询串。
selectNodes(query):
得到的是
xml
根节点下的所有满足
xpath
的节点;
参数是
Xpath
查询串。
Node:
节点对象
4.5.4 Xpath读取XML
3)
数据准备
book.xml
<?xml version="1.0" encoding="UTF-8" ?>
<bookstore>
<book id="book1">
<name>金瓶梅</name>
<author>金圣叹</author>
<price>99</price>
</book>
<book id="book2">
<name>红楼梦</name>
<author>曹雪芹</author>
<price>69</price>
</book>
<book id="book3">
<name>Java编程思想</name>
<author>埃克尔</author>
<price>59</price>
</book>
</bookstore>
4)
代码示例
1.
使用
selectSingleNode
方法 查询指定节点中的内容
/*
* 1. 使用selectSingleNode方法 查询指定节点中的内容
* */
@Test
public void test1() throws DocumentException {
//1.创建解析器对象
SAXReader sr = new SAXReader();
//2.获取文档对象
Document document =
sr.read("H:\\jdbc_work\\xml_task03\\src\\com\\lagou\\xml03\\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());
}
2.
使用
selectSingleNode
方法 获取属性值
,
或者属性值对应的节点
/*
* 2.使用selectSingleNode方法 获取属性值,或者属性值对应的节点
* */
@Test
public void test2() throws DocumentException {
//1.创建解析器对象
SAXReader sr = new SAXReader();
//2.获取文档对象
Document document =
sr.read("H:\\jdbc_work\\xml_task03\\src\\com\\lagou\\xml03\\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);
}
3.
使用
selectNodes()
方法 获取对应名称的所有节点
/*
* 3.使用 selectNodes()方法 获取对应名称的所有节点
*
* */
@Test
public void test3() throws DocumentException {
//1.创建解析器对象
SAXReader sr = new SAXReader();
//2.获取文档对象
Document document =
sr.read("H:\\jdbc_work\\xml_task03\\src\\com\\lagou\\xml03\\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());
}
}
5. JDBC自定义XML
5.1 定义配置文件
1)
创建自定义
xml
文件
,
保存 数据库连接信息
jdbc-config.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">123456</property>
</jdbc>
5.2 编写工具类(配置式)
2)
编写工具类
,
使用
xpath
读取数据库信息
public class JDBCUtils {
//1. 定义字符串变量, 记录获取连接所需要的信息
public static String DRIVERNAME;
public static String URL;
public static String USER;
public static String PASSWORD;
//2.静态代码块
static {
try {
//使用 xpath读取 xml中的配置信息
SAXReader sr = new SAXReader();
Document document =
sr.read("H:\\workspace01\\JDBC_day02\\src\\com\\lagou\\xml03\\jdbc-config.xml");
Node node =
document.selectSingleNode("/jdbc/property[@name='driverClass']");
//System.out.println(node.getText());
DRIVERNAME = node.getText();
URL =
document.selectSingleNode("/jdbc/property[@name='jdbcUrl']").getText();
USER =
document.selectSingleNode("/jdbc/property[@name='user']").getText();
PASSWORD =
document.selectSingleNode("/jdbc/property[@name='password']").getText();
//注册驱动
Class.forName(DRIVERNAME);
} catch (Exception e) {
e.printStackTrace();
}
}
//3.获取连接的静态方法
public static Connection getConnection(){
try {
//获取连接对象
Connection connection = DriverManager.getConnection(URL, USER,
PASSWORD);
//返回连接对象
return connection;
} catch (SQLException e) {
e.printStackTrace();
return null;
}
}
}
5.3 测试工具类
3)
测试
:
获取所有员工的姓名
//获取所有员工的姓名
public static void main(String[] args) {
try {
//1.获取连接
Connection connection = JDBCUtils.getConnection();
//2.获取 statement ,执行SQL
Statement statement = connection.createStatement();
String sql = "select * from employee";
//3.处理结果集
ResultSet resultSet = statement.executeQuery(sql);
while(resultSet.next()){
String ename = resultSet.getString("ename");
System.out.println(ename);
}
} catch (SQLException e) {
e.printStackTrace();
}
}
总结: