一:XML基本介绍
1、概述:
- XML即可扩展标记语言(Extensible Markup Language)
- W3C在1998年2月发布1.0版本,2004年2月又发布1.1版本,但因为1.1版本不能向下兼容1.0版本,所以1.1没有人用。同时,在2004年2月W3C又发布了1.0版本的第三版。我们要学习的还是1.0版本 !
- 特点
- 可扩展的, 标签都是自定义的
- 语法十分严格
- XML的作用:
功能
|
说明
|
存储数据
|
通常,我们在数据库中存储数据。不过,如果希望数据的可移植性更强,我们可以 把数据存储 XML
文件中
|
配置文件
|
作为各种技术框架的配置文件使用
(
最多
)
|
在网络中传输
|
客户端可以使用
XML
格式向服务器端发送数据
,
服务器接收到
xml
格式数据
,
进行解析
|
2、XML的语法
- xml文档声明格式
-
文档声明必须为结束;
-
文档声明必写在第一行;
-
1)
语法格式
:
<?xml version="1.0" encoding="UTF-8"?>
2)
属性说明
:
versioin
:指定
XML
文档版本。必须属性,因为我们不会选择
1.1
,只会选择
1.0
;
encoding
:指定当前文档的编码。可选属性,默认值是
utf-8
;
- 元素
- 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/>
- 属性:
- 1. 属性是元素的一部分,它必须出现在元素的开始标签中
- 2. 属性的定义格式:属性名=属性值,其中属性值必须使用单引或双引
- 3. 一个元素可以有0~N个属性,但一个元素中不能出现同名属性
- 4. 属性名不能使用空格、冒号等特殊字符,且必须以字母开头
<bean id="" class=""> </bean>
- 注释:
-
XML 的注释,以 “ <!--” 开始,以 “--> ” 结束。注释内容会被 XML 解析器忽略!
-
-
使用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>
<employee eid = "4">
<ename>李白</ename>
<age>50</age>
<sex>男</sex>
<salary>15000</salary>
<empdate>2010-01-01</empdate>
</employee>
</employees>
3、xml约束:
- 在XML技术里,可以编写一个文档来约束一个XML文档的书写规范,这称之为XML约束。
- 常见的xml约束:
- DTD
- Schema
- 作为程序员只要掌握两点
- 会阅读
- 会引入
- 不用自己编写
- DTD约束:
-
DTD ( Document Type Defifinition ),文档类型定义,用来约束 XML 文档。规定 XML 文档中元素的名 称,子元素的名称及顺序,元素的属性等。
-
-
编写DTD
-
开发中,我们不会自己编写 DTD 约束文档
-
常情况我们都是通过框架提供的 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+):student 代表根元素
student+:根标签中 至少有一个student子元素
student (name,age,sex):student标签中可以包含的子元素
#PCDATA:普通的文本内容
ATTLIST:用来定义属性
student number ID:student标签中有个id属性叫做number
#REQUIRED : number属性必须填写
id唯一的值 不能重复 值只能是字母或者下划线开头
-->
- 引入DTD
-
引入 dtd 文档到 xml 文档中 , 两种方式
- 内部dtd:将约束规则定义在xml文档中(本地)
-
外部 dtd :将约束的规则定义在外部的 dtd 文件中(网络)
-
student.xml
-
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE students SYSTEM "E:\java\the second stage\Module 2\jdbc_task02\src\com\lagou\xml02\dtd\student.dtd">
<students>
<student number="S1">
<name>大海</name>
<age>20</age>
<sex>男</sex>
</student>
<student number="S2">
<name>小海</name>
<age>10</age>
<sex>女</sex>
</student>
</students>
- Schema约束
- 什么是Schema
-
Schema 是新的 XML 文档约束 , 比 DTD 强大很多,是 DTD 替代者;
-
Schema 本身也是 XML 文档,但 Schema 文档的扩展名为 xsd ,而不是 xml 。
-
Schema 功能更强大,内置多种简单和复杂的数据类型
-
Schema 支持命名空间 ( 一个 XML 中可以引入多个约束文档 )
-
-
Schema约束示例
-
student.xsd
-
- 什么是Schema
<?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的根元素
- 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>20</age>
<sex>male</sex>
</student>
</students>
4、XML解析
- 解析概述
-
当将数据存储在 XML 后,我们就希望通过程序获得 XML 的内容。如果我们使用 Java 基础所学习的 IO 知识是可以完成的,不过你需要非常繁琐的操作才可以完成,且开发中会遇到不同问题(只读、读写)。 人们为不同问题提供不同的解析方式,并提交对应的解析器,方便开发人员操作XML 。
-
-
XML解析方式:
-
开发中比较常见的解析方式有两种,如下:
-
DOM :要求解析器把整个 XML 文档装载到内存,并解析成一个 Document 对象。
-
优点:元素与元素之间保留结构关系,故可以进行增删改查操作。
-
缺点: XML 文档过大,可能出现内存溢出显现。
-
-
SAX :是一种速度更快,更有效的方法。它逐行扫描文档,一边扫描一边解析。并以事件驱动的方式进行具体解析,每执行一行,都将触发对应的事件。(了解)
- 优点:占用内存少 处理速度快,可以处理大文件
- 缺点:只能读,逐行后将释放资源。
-
-
- XML常见的解析器:解析器:就是根据不同的解析方式提供的具体实现。有的解析器操作过于繁琐,为了方便开发人员,有提供易于操作的解析开发包
-
JAXP : sun 公司提供的解析器,支持 DOM 和 SAX 两种思想
-
DOM4J :一款非常优秀的解析器 , Dom4j 是一个易用的、开源的库,用于 XML , XPath 和 XSLT 。 它应用于Java 平台,采用了 Java 集合框架并完全支持 DOM , SAX 和 JAXP 。
-
Jsoup:jsoup 是一款 Java 的 HTML 解析器 , 也可以解析 XML
-
PULL : Android 内置的 XML 解析方式,类似 SAX 。
-
- dom4j的使用
- 导入jar包
- API介绍
-
使用核心类 SaxReader 加载 xml 文档获得 Document ,通过 Document 对象获得文档的根元素,然后就 可以操作了
-
常用 API 如下:
-
SaxReader 对象
-
read(…) 加载执行 xml 文档
-
-
Document 对象
-
getRootElement() 获得根元素
-
-
Element 对象
-
elements(…) 获得指定名称的所有子元素。可以不指定名称
- element(…) 获得指定名称的第一个子元素。可以不指定名称
- getName() 获得当前元素的元素名
- attributeValue(…) 获得指定属性名的属性值
- elementText(…) 获得指定名称子元素的文本值
- getText() 获得当前元素的文本内容
-
-
-
准备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{3}"/>
</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="001">
<name>张百万</name>
<age>25</age>
<hobby>抽烟</hobby>
</user>
<user id="002">
<name>于谦</name>
<age>55</age>
<hobby>烫头</hobby>
</user>
<user id="003">
<name>小斌</name>
<age>25</age>
<hobby>喝酒</hobby>
</user>
</users>
读取XML
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.junit.Test;
import java.util.List;
public class TestDOM4j {
// 获取xml文件中的所有的元素(标签)
@Test
public void test1() throws DocumentException {
// 获取xml解析对象
SAXReader reader = new SAXReader();
// 解析xml 获取文档对象 document
Document document = reader.read("E:\\java\\the second stage\\Module 2\\jdbc_task02\\src\\com\\lagou\\xml03\\user.xml");
// 获取根元素
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());
}
}
}
// 获取xml中标签的文本信息和属性信息
@Test
public void test2() throws DocumentException {
// 获取解析xml的SAXReader
SAXReader reader = new SAXReader();
// 获取文档对象
Document document = reader.read("E:\\java\\the second stage\\Module 2\\jdbc_task02\\src\\com\\lagou\\xml03\\user.xml");
// 获取根节点
Element rootElement = document.getRootElement();
// 获取子节点 user
List<Element> elements = rootElement.elements();
// 获取集合中的第一个子节点
Element user = elements.get(0);
// 获取节点中的文本信息
String id = user.attributeValue("id");// 获取熟悉id得值
String name = user.elementText("name");
String age = user.elementText("age");
String hobby = user.element("hobby").getText();
System.out.println(id+" "+ name +" "+ age + " " + hobby);
}
}
- xpath方式读取xml
- xpath介绍
-
XPath 是一门在 XML 文档中查找信息的 语言 。 可以是使用 xpath 查找 xml 中的内容。
-
XPath 的好处
- 由于DOM4J在解析XML时只能一层一层解析,所以当XML文件层数过多时使用会很不方便,结合XPATH就可以直接获取到某个元素
-
- xpath介绍
需要再次导入jaxen-1.1-beta-6.jar
- XPath基本语法介绍:
使用
dom4j
支持
xpath
的操作的几种主要形式
语法
|
说明
|
/AAA/DDD/BBB
|
表示一层一层的,
AAA
下面
DDD
下面的
BBB
|
//BBB
|
表示和这个名称相同,表示只要名称是
BBB
,都得到
|
//*
|
所有元素
|
BBB[1] , BBB[last()]
|
第一种表示第一个
BBB
元素
,
第二种表示最后一个
BBB
元素
|
//BBB[@id]
|
表示只要
BBB
元素上面有
id
属性,都得到
|
//BBB[@id='b1']
|
表示元素名称是
BBB,
在
BBB
上面有
id
属性,并且
id
的属性值是
b1
|
API介绍
常用方法:
- selectSingleNode(query): 查找和 XPath 查询匹配的一个节点。
- 参数是Xpath 查询串。
- selectNodes(query): 得到的是xml根节点下的所有满足 xpath 的节点;
- 参数是Xpath 查询串。
- Node: 节点对象
XPath读取xml
数据准备 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>
代码示例:
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;
import org.junit.Test;
import java.util.List;
public class TestXPath {
/*
* 使用selectSingNode() 方法查询指定的节点信息
* */
@Test
public void test1() throws DocumentException {
// 创建xml解析对象
SAXReader reader = new SAXReader();
Document document = reader.read("E:\\java\\the second stage\\Module 2\\jdbc_task02\\src\\com\\lagou\\xml04\\book.xml");
// 通过selectSingNode()方法获取name节点
Node node = document.selectSingleNode("/bookstore/book/name");
System.out.println("节点的名称:"+ node.getName());
System.out.println("书名:"+ node.getText());
// 获取第二本书的书名
Node node1 = document.selectSingleNode("/bookstore/book[2]/name");
System.out.println("书名:"+ node1.getText());
}
/*
* 使用selectSingNode()方法获取属性值 或者通过属性值获取到节点的信息
* */
@Test
public void test2() throws DocumentException {
SAXReader reader = new SAXReader();
Document document = reader.read("E:\\java\\the second stage\\Module 2\\jdbc_task02\\src\\com\\lagou\\xml04\\book.xml");
// 获取第一个book节点中的id属性值
Node node = document.selectSingleNode("/bookstore/book/attribute::id");
System.out.println("第一个book的id属性值"+node.getText());
// 获取最后一个book节点id属性值
Node node1 = document.selectSingleNode("/bookstore/book[last()]/attribute::id");
System.out.println("最后一个book节点中的属性值:"+ node1.getText());
// 通过id值获取节点中的信息
Node node2 = document.selectSingleNode("/bookstore/book[@id = 'book2']");
String name = node2.selectSingleNode("name").getText();
System.out.println("id为book2的节点书名是:"+name);
}
/*
* 使用selectNodes() 获取所有指定名称的节点
* */
@Test
public void test3() throws DocumentException {
SAXReader reader = new SAXReader();
Document document = reader.read("E:\\java\\the second stage\\Module 2\\jdbc_task02\\src\\com\\lagou\\xml04\\book.xml");
// 查询所有的节点
List<Node> list = document.selectNodes("//*");
for (Node node : list) {
System.out.println("节点名:"+node.getName());
}
// 获取所有的书名
List<Node> list1 = document.selectNodes("//name");
for (Node node : list1) {
System.out.println("书名:"+ node.getText());
}
// 获取id值为book1的节点中所有内容
List<Node> list2 = document.selectNodes("/bookstore/book[@id='book1']//*");
for (Node node : list2) {
System.out.println(node.getName()+":"+node.getText());
}
}
}
5、JDBC自定义XML
-
创建自定义 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">123456</property>
</jdbc>
- 编写工具类(配置式)
编写工具类,使用xpath 读取数据库信息
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.io.SAXReader;
import java.sql.Connection;
import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.SQLException;
public class JDBCUtils {
// 定义字符串变量 保持连接信息
public static String DRIVERNAME;
public static String URL;
public static String USER;
public static String PASSWORD;
// 静态代码块
static {
// 使用XPATH语法 对xml中的数据进行读取
SAXReader reader = new SAXReader();
try {
Document document = reader.read("E:\\java\\the second stage\\Module 2\\jdbc_task02\\src\\com\\lagou\\xml05\\jdbc-config.xml");
// 获取驱动名称
DRIVERNAME = document.selectSingleNode("/jdbc/property[@name='driverClass']").getText();
// 获取URL
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();
}
}
// 获取连接
public static Connection getConnection(){
try {
Connection connection = DriverManager.getConnection(URL, USER, PASSWORD);
return connection;
} catch (SQLException e) {
e.printStackTrace();
return null;
}
}
}
- 测试工具类
测试 : 获取所有员工的姓名
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 {
// 获取连接
Connection connection = JDBCUtils.getConnection();
// 获取Statement对象 执行sql
Statement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery("select * from employee");
// 处理结果集
while (resultSet.next()){
String name = resultSet.getString("ename");
System.out.println("员工的姓名:"+name);
}
// 关闭资源
resultSet.close();
statement.close();
connection.close();
}
}