1 XML基本介绍
XML是可扩展标记语言,特点是是可扩展的,标签都是自定义,且语法严格,XML主要用来存储数据、作为配置文件以及在网络中传输数据。
接下来介绍下XML的语法:
XML文档声明格式
文档声明必须以< ? xml开头,以?>结尾,并且文档声明必须写在第一行。具体语法格式如下:
<?xml version="1.0" encoding="utf-8"?>
元素
Element元素是X ML文档中重要的组成部分,且元素的命名规则是:
- 不能使用空格,不能使用冒号
- xml标签是区分大小写的
- xml只有一个根元素
语法格式:
<?xml version="1.0" encoding="utf-8"?>
<users>
<hello>
大家好
</hello>
<hello>
<a>你好</a>
</hello>
<close/>
</users>
<!--
上面users就是根元素,它是其它元素的父元素
hello就是普通元素,是由开始标签、元素体以及结束标签组成,其中元素体可以是文本,也可以是元素
close是空元素,只有开始标签,没有结束标签,且元素自己闭合
-->
属性
<bean id="" class=""></bean>
属性是元素的一部分,他必须出现在元素的开始标签中,且属性定义格式是:属性名=属性值,其中属性值必须用单引号或者双引号括起来;一个元素可以有0到n个属性,但一个元素中不能出现同名属性,且属性名不能使用空格、冒号等特殊字符,必须以字母开头。
注释
xml的注释是以< !--快开始,以 -- >结束,注释的内容会被XML解释器忽略掉
接下来使用XML描述一个数据表中的数据,具体代码如下:
<?xml version="1.0" encoding="utf-8"?>
<employees>
<employee eid="1">
<ename>林黛玉</ename>
<age>18</age>
</employee>
<employee eid="2">
<ename>刘备</ename>
<age>38</age>
</employee>
<employee eid="3">
<ename>关羽</ename>
<age>48</age>
</employee>
</employees>
xml约束
在xml技术里,可以编写一个文档来约束一个xml文档的书写规范,这就是xml约束。常见的xml约束有:DTD和Schema,在日常开发中只要求会阅读和会引入,不用自己编写xml约束。
2 DTD约束
DTD文档类型定义,用来约束xml文档。规定xml文档中的元素的名称,子元素的名称和顺序,元素的属性等。
<!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 : student标签中 有一个ID属性 叫做 number
#REQUIRED : number的属性必须填写
ID 唯一的值 不能重复 值只能是字母或者下划线开头
-->
引入dtd文档到xml文档中的两种方式:
- 内部dtd:将约束规则定义在xml文档中
- 外部dtd:将约束的规则定义在外部的dtd文件中
接下来以student.xml为例:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE students SYSTEM "H:\jdbc_work\xml_task03\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>18</age>
<sex>女</sex>
</student>
</students>
3 Schema约束
Schema约束是最新的xml文档约束,要比DTD更加强大,是DTD的替代者,Schema本身也是XML文档,但是Schema文档的扩展名为xsd,而不是xml,Schema强大就强大在内置多种简单和复杂的数据类型,且支持命名空间(一个XML中可以引入多个约束文档)
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="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 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>200</age>
<sex>male</sex>
</student>
<student number="hehe_4567">
<name>张三</name>
<age>200</age>
<sex>male</sex>
</student>
</students>
4 XML解析
当我们定义完XML文档后,当想要通过程序来获得XML文档中的内容,就需要使用XML解析,在开发中比较常见的的解析方式是:
- DOM:要求解析器将整个XML文档装载到内存中,并解析成一个Docunment对象,这种方式的优点是:元素和元素之间保留结构关系,可以进行增删改查;缺点就是XML文档过大,可能会存在内存泄漏情况
- SAX:是一种速度更快,更加有效的方法,它是逐行扫描文档,一边扫描一边解析,以事件驱动的方式进行解析,没执行一行,都会触发对应的事件。优点是:占用内存少,处理速度快,可以处理大文件;缺点是:只能读,逐行解析后释放资源
基于上面两种解析方式,市面上就出现了解析器,根据不同的解析方式提供具体的实现,具体解析器有:
- JAXP:支持DOM和SAX两种方式
- DOM4J:一款优秀的解析器,应用于Java平台,采用Java集合框架并完全支持DOM、SAX和JAXP
- Jsoup:一款Java的HTML解析器,也可以解析XML
- PULL:Android内置的XML解析器
DOM4J的使用:
使用之前先导包,在介绍解析相关的API,使用核心类SaxReader加载XML文档获得Document,再通过Document对象获得根元素,然后就可以进行解析操作。
常用API如下:
-
SaxReader对象:read(...)方法加载执行xml文档
-
Document对象:getRootElemet()获得根元素
-
Element对象: elements(...) 获得指定名称的所有子元素,可以不指定名称
element(...) 获得指定名称的第一个元素,可不指定名称
getName(...)获得当前元素的元素名
attributeValue(...)获得指定属性名的属性值
elementText(...)获得指定名称元素的文本值
getText() 获得当前元素的文本内容
编写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:minIn clusive 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 {
//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;
}
}
//获取XML中标签的文本信息 和 属性信息
@Test
public void test2() throws DocumentException {
//1.获取解析XML的 SAXReader
SAXReader reader = new SAXReader();
//2.获取文档对象
Document document = reader.read("H:\\jdbc_work\\xml_task03\\src\\com\\lagou\\xml03\\user.xml");
//3.获取根节点
Element rootElement = document.getRootElement();
//4.获取子节点 user
List<Element> elements = rootElement.elements();
//5.获取集合中的第一个 子节点
Element user = elements.get(0);
//6.获取节点中的文本信息
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);
}
}
5 xpath方式读取xml
xpath是一门在xml文档中查找信息的语言,使用xpath的好处是:不用想DO M4J那样在解析XML时只能一层一层解析,这在XML文件层数较多时就非常不方便,结合xpath就可以直接获取到某个元素。
xpath基本语法介绍:
语法 | 介绍 |
---|---|
/AAA/DDD/BBB | 表示一层一层的,AAA下面DDD下面的BBB |
//BB | 表示和这个名称相同,只要名称和BBB相同,都得到 |
//* | 所有元素 |
BBB[1],BBB[last] | 前面表示第一个BBB元素,后一个表示最后一个BBB元素 |
//BB[@id] | 只要BBB元素上面有id属性,都得到 |
//BB[@id='b1'] | 得到BBB元素上面有id属性等于b1的元素 |
API介绍:
- selectSingleNode(query)查找和XPath查询匹配的一个节点 query是XPath查询串
- selectNodes(query)得到的是xml根结点下所有满足xpath的节点
- Node 节点对象
Xpath读取book.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>
读取xml的代码
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 XpathTest {
@Test
public void test1() throws DocumentException {
SAXReader sr=new SAXReader();
Document dm=sr.read("/Users/bijinxiong/IdeaProjects/jdbc/xml/src/book.xml");
Node node = dm.selectSingleNode("bookstore/book/name");
System.out.println("节点名"+node.getName());
System.out.println("书名"+node.getText());
Node node1 = dm.selectSingleNode("bookstore/book[2]/name");
System.out.println("查询到的第二本书是:");
System.out.println("节点名"+node1.getName());
System.out.println("书名"+node1.getText());
}
@Test
public void test2() throws DocumentException {
SAXReader sr=new SAXReader();
Document dm=sr.read("/Users/bijinxiong/IdeaProjects/jdbc/xml/src/book.xml");
Node node = dm.selectSingleNode("bookstore/book/attribute::id");
System.out.println("第一本书的id:"+node.getText());
Node node1 = dm.selectSingleNode("bookstore/book[last()]/attribute::id");
System.out.println("第一本书的id:"+node1.getText());
Node node2 = dm.selectSingleNode("bookstore/book[@id='book2']");
String name = node2.selectSingleNode("name").getText();
System.out.println("id为book2的书名是"+name);
}
@Test
public void test3() throws DocumentException {
SAXReader sr=new SAXReader();
Document dm=sr.read("/Users/bijinxiong/IdeaProjects/jdbc/xml/src/book.xml");
List<Node> list = dm.selectNodes("//*");
for(Node node:list){
System.out.println("节点名:"+node.getName());
}
List<Node> list1 = dm.selectNodes("//name");
for(Node node:list1){
System.out.println("所有书名是"+node.getText());
}
List<Node> list2 = dm.selectNodes("bookstore/book[@id='book1']//*");
for(Node node:list2){
System.out.println(node.getName()+" "+node.getText());
}
}
}
6 JDBC自定义XML
创建自定义的JDBC配置文件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">root</property>
</jdbc>
工具类
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.io.SAXReader;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class JDBCUtils {
public static String DRIVERNAME;
public static String URL;
public static String USERNAME;
public static String PASSWORD;
static {
SAXReader sr = new SAXReader();
try {
Document dc = sr.read("/Users/bijinxiong/IdeaProjects/jdbc/xml/src/jdbc_config.xml");
DRIVERNAME=dc.selectSingleNode("/jdbc/property[@name='driverClass']").getText();
URL=dc.selectSingleNode("/jdbc/property[@name='jdbcUrl']").getText();
USERNAME=dc.selectSingleNode("/jdbc/property[@name='user']").getText();
PASSWORD=dc.selectSingleNode("/jdbc/property[@name='password']").getText();
Class.forName(DRIVERNAME);
} catch (DocumentException | ClassNotFoundException e) {
e.printStackTrace();
}
}
public static Connection getConnection() throws SQLException {
Connection con= DriverManager.getConnection(URL,USERNAME,PASSWORD);
return con;
}
}
测试类
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class test {
public static void main(String[] args) throws SQLException {
Connection con=JDBCUtils.getConnection();
Statement statement = con.createStatement();
String sql="select ename from employee where eid=2 ";
ResultSet resultSet = statement.executeQuery(sql);
while (resultSet.next()){
System.out.println("eid为2的人是:"+resultSet.getString("ename"));
}
if(null!=con&&null!=statement){
statement.close();
con.close();
}
}
}