XML技术
XML是一种可扩展标记语言,用来标记数据、定义数据类型,1998年由W3W发布1.0.版本,与HTML语言相比,可以自定义可扩展标签格式,但是语法严格。
XML可以用来存储数据,可移植性强,主要充当配置文件,自定义可扩展标签格式,与properties配置文件不同(键值对对应信息),可以在网络中传递数据并解析
一、XML语法
1. 文档声明:xml文件首行必须填写xml文档说明,包括版本和编码。 <?xml version="1.0" encoding="utf-8" ?>
2. 元素
- 开始结束标签说明不能含有空格、冒号等,可以重复成对出现,xml标签命名区分大小写
- 只能有一个根元素,他是其他元素的父元素
- 普通元素包含开始标签,元素体,结束标签,元素体可以是文本也可以是标签
- 空元素只有开始标签,元素自己闭合,例<close/>
- 文档注释<!-- 注释部分 -->包裹
3. 属性
- 属性只能在开始标签里添加,说明当前标签的属性
- 属性定义格式: 属性名=属性值, 属性值必须用单引号或双引号包裹
- 一个元素可以有多个属性,但一个元素中不能出现同名的属性
- 属性不能用空格冒号等特殊字符,必须以字母开头
<?xml version="1.0" encoding="utf-8"?> <employees> <employee eid="1"> <ename>李清照</ename> <age>22</age> <sex>女</sex> <salary>4000</salary> <empdate>2018-11-12</empdate> </employee> <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>6000</salary> <empdate>2019-01-01</empdate> </employee> </employees>
二、XML约束
不同用户自定义标签不同,导致解析有不同,编写一个文档来约束一个XML文档的书写规范,保证数据的安全性和规范性,主要有DTD约束和Schema约束
1.DTD约束,文件格式以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 (name,age,sex) :student包含的子元素按顺序出现 (#PCDATA): 普通文本内容 ATTLIST: 用来定义属性 student number ID #REQUIRED: student子元素中 有一个ID属性叫做 number,是必须填写的 ID: 唯一 值只能是字母或者下划线开头 #REQUIRED:必须填写 -->
- 引入dtd文档到xml文档中
- 内部dtd:将约束规则定义在xml文档中 <!DOCTYPE 根标签名 SYSTEM "dtd文件的位置">
- 外部dtd:将约束的规则定义在外部的dtd文件中 <!DOCTYPE 根标签名 PUBLIC "dtd文件名" "dtd文件的位置URL">
- 内部dtd:将约束规则定义在xml文档中 <!DOCTYPE 根标签名 SYSTEM "dtd文件的位置">
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE students SYSTEM "student.dtd"> <students> <student number="S1"> <name>李清照</name> <age>20</age> <sex>女</sex> </student> <student number="s2"> <name>李白</name> <age>30</age> <sex>男</sex> </student> </students>
2.schema约束
- 是一种新的文档约束,用法和xml一样,但是文件格式以xsd结尾,功能强大,能接受多种数据类型和命名空间
- 阅读理解
<?xml version="1.0"?> <!-- 引用 www.w3.org/2001/XMLSchema命名空间下的数据类型前面都要加上xsd --> <xsd:schema xmlns="http://www.lagou.com/xml" xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.lagou.com/xml" elementFormDefault="qualified"> <!-- 根元素是students ,类型是自定义的studentType--> <xsd:element name="students" type="studentsType"/> <xsd:complexType name="studentsType"> <!-- studentType 包括元素名:student, 最少出现0次,可以出现很多次--> <xsd:sequence> <xsd:element name="student" type="studentType" minOccurs="0" maxOccurs="unbounded"/> </xsd:sequence> </xsd:complexType> <xsd:complexType name="studentType"> <!-- tudentType的构成包括String name, 定义的age格式和性别格式 --> <xsd:sequence> <xsd:element name="name" type="xsd:string"/> <xsd:element name="age" type="ageType" /> <xsd:element name="sex" type="sexType" /> </xsd:sequence> <!-- 元素属性 必须要有number--> <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"> <!-- 年龄是0~200之间的整数--> <xsd:restriction base="xsd:integer"> <xsd:minInclusive value="0"/> <xsd:maxInclusive value="200"/> </xsd:restriction> </xsd:simpleType> <xsd:simpleType name="numberType"> <!-- number是字符串类型,必须以hehe_开头,最多出现4个数字--> <xsd:restriction base="xsd:string"> <xsd:pattern value="hehe_\d{4}"/> </xsd:restriction> </xsd:simpleType> </xsd:schema>
- 引入约束
- 查看schema文档,找到根元素,在xml文档中写出来
- 指明根元素来自哪个命名空间。使用xmlns指令来声明
- 引入w3c的标准命名空间 "http://www.w3.org/2001/XMLSchema"
- 使用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:schmaLocation="http://www.lagou.com/xml student.xsd"> <student number="hehe_1234"> <name>pc</name> <age>29</age> <sex>male</sex> </student> <student number="hehe_12"> <name>pcmv</name> <age>20</age> <sex>male</sex> </student> </students>
三、XML解析
- XML 解析方式通常有2中,DOM和SAX;
- DOM要求解析器把整个XML文档装载到内存,并解析成一个Document对象,以DOM树结构存储数据,可以进行增删改查CRUD,但是占用内存大,全部读取,XML内存过大可能会出现内存溢出
- SAX以事件驱动的方式进行具体解析,每执行一行,都将触发对应的事件,逐行读取,占用内存小,只能用于读解析,读完后释放资源
- 常见的XML解析器
- JAXP:sun公司提供的解析器,支持DOM和SAX
- Dom4j:易用的、开源的库,用于XML,XPath和XSLT,应用于Java平台,采用了Java集合框架并完全支持DOM,SAX和JAXP
- jsoup:一款Java 的HTML解析器 ,也可以解析XML
- PULL:Android内置的XML解析方式,类似SAX ,适用于内存小的应用
- JAXP:sun公司提供的解析器,支持DOM和SAX
- Dom4j的使用
- 导入dom4j的jar包
![]()
-
使用核心类SaxReader 加载xml文件获取document对象,通过document对象获得根元素 常用API如下:
- SaxReader对象通过read()加载执行xml文档
- Document对象通过getRootElement()获取根元素
- Element对象 中 elements() 获得指定名称的所有子元素 ;element() 获得指定名称的第一个元素 ;getName() 获得当前元素元素名 ; attrubuteValue() 获得指定属性名的属性值 ; elementText()获得指定名称子元素的文本值 ; getText() 获得当前元素的文本内容
- 导入dom4j的jar包
package Dom4j; import org.dom4j.Document; import org.dom4j.DocumentException; import org.dom4j.Element; import org.dom4j.io.SAXReader; import org.junit.Test; import javax.print.Doc; import java.util.List; public class Dom4j { @Test public void test01() throws DocumentException { //1. 创建SaxReader对象 SAXReader saxReader=new SAXReader(); //2. 解析XML获取document文档 Document document=saxReader.read("C:\\Users\\Administrator\\Desktop\\javaJDBC\\jdbc03\\src\\Dom4j\\user.xml"); //3.获取根元素 Element root= document.getRootElement(); //4. 读取根元素名称和根元素下各子标签的名称 System.out.println(root.getName());//根元素名称 List<Element> elements = root.elements(); for (Element element : elements) { System.out.println("根标签下的节点名称"+element.getName());//子标签名称 List<Element> list = element.elements(); for (Element element1 : list) { System.out.println("子标签下的节点名称"+element1.getName()); //子标签下的元素 } } } @Test public void test02() throws DocumentException { //1.创建SaxReader对象 SAXReader saxReader=new SAXReader(); //2.解析xml文件获取document Document document= saxReader.read("C:\\Users\\Administrator\\Desktop\\javaJDBC\\jdbc03\\src\\Dom4j\\user.xml"); //3.获取根节点 Element root = document.getRootElement(); //4. 获取具体节点的内容 List<Element> elements = root.elements(); //按索引获取第一个索引下的标签 Element user = elements.get(0); //获取具体信息 String id = user.attributeValue("id"); String name = user.elementText("name"); String age = user.elementText("age"); String hobby = user.element("hobby").getText(); System.out.println("id="+id+" "+"name"+name+" "+"age"+age+" "+"hobby"+hobby); } }
- XPath的使用:dom4j只能一层一层解析XML文件,按结构树解析,用XPath可以直接获取XML中的元素信息
- 导入jar包
![]()
- 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)查找单个节点;selectNodes(query)查找XML根节点下的满足条件的所有节点;Node是节点对象
package XPath; 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 test01() throws DocumentException { //1. 创建SaxReader SAXReader saxReader= new SAXReader(); //2. 创建document对象 Document document= saxReader.read("C:\\Users\\Administrator\\Desktop\\javaJDBC\\jdbc03\\src\\XPath\\book.xml"); //3. 获取根节点下的子节点的name节点 Node node = document.selectSingleNode("/bookstore/book/name"); System.out.println("节点名为"+node.getName()); System.out.println("书名"+node.getText()); //4. 获取第二本书 Node node1 = document.selectSingleNode("/bookstore/book[2]/name"); System.out.println("节点名为"+node1.getName()); System.out.println("书名"+node1.getText()); //5. 获取最后一本书 Node node2 = document.selectSingleNode("/bookstore/book[last()]/name"); System.out.println("节点名为"+node2.getName()); System.out.println("书名"+node2.getText()); //6.获取第一个book节点的 id属性的值 Node node3 = document.selectSingleNode("/bookstore/book/attribute::id"); System.out.println("属性名为"+node3.getName()); System.out.println("属性值"+node3.getText()); //7.获取最后一个book节点的 id属性的值 Node node4 = document.selectSingleNode("/bookstore/book[last()]/attribute::id"); System.out.println("属性名为"+node4.getName()); System.out.println("属性值"+node4.getText()); //8.获取id属性值为 book2的 书名 Node node5 = document.selectSingleNode("/bookstore/book[@id='book2']"); System.out.println("书名为"+node5.selectSingleNode("name").getText()); } @Test public void test02() throws DocumentException { //1. 创建SaxReader SAXReader saxReader=new SAXReader(); //2. 创建document对象 Document document=saxReader.read("C:\\Users\\Administrator\\Desktop\\javaJDBC\\jdbc03\\src\\XPath\\book.xml"); //3. 获取所有节点 List<Node> list = document.selectNodes("//*"); for (Node node : list) { System.out.println(node.getName()); } //4. 获取所有书名 List<Node> list1 = document.selectNodes("//name"); for (Node node : list1) { System.out.println("书名:"+node.getText()); } //5.获取id属性值为 book2的 所有节点信息 List<Node> list2 = document.selectNodes("/bookstore/book[@id='book2']//*"); for (Node node : list2) { System.out.println(node.getName()+"="+node.getText()); } } }
四、JDBC自定义XML
1.自定义jdbc-config.xml文件
<?xml version="1.0" encoding="UTF-8" ?>
<jdbc-config>
<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>
<property name="initialPoolSize">10</property>
<property name="maxIdleTime">30</property>
<property name="maxPoolSize">100</property>
<property name="minPoolSize">10</property>
</jdbc-config>
2. 先写jdbcutils工具类
package JDBCUtils;
import org.dom4j.Document;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;
import java.sql.*;
public class JDBCUtils {
//1. 定义成员变量
public static String DRIVERNAME;
public static String URL;
public static String USER;
public static String PASSWORD;
//2.静态代码块解析xml文件并
static {
// 创建SaxReader对象
SAXReader reader = new SAXReader();
//获取DOCUMENT 对象
try {
Document document = reader.read("C:\\Users\\Administrator\\Desktop\\javaJDBC\\jdbc03\\src\\JDBCUtils\\jdbc-config.xml");
//解析需要获取的指定名称
Node node = document.selectSingleNode("/jdbc-config/property[@name='driverClass']");
DRIVERNAME=node.getText();
Node node1 = document.selectSingleNode("/jdbc-config/property[@name='jdbcUrl']");
URL=node1.getText();
Node node2 = document.selectSingleNode("/jdbc-config/property[@name='user']");
USER=node2.getText();
Node node3 = document.selectSingleNode("/jdbc-config/property[@name='password']");
PASSWORD=node3.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;
}
}
//4.关闭流
public static void close(Connection con, Statement statement){
if (con!=null && statement!=null){
try {
statement.close();
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
public static void close(Connection con, Statement statement, ResultSet resultSet){
if (resultSet!=null){
try {
resultSet.close();
JDBCUtils.close(con,statement);
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
3. 进行测试
package JDBCUtils;
import java.sql.*;
public class JDBCtest {
public static void main(String[] args) {
//1.获取连接
Connection connection = JDBCUtils.getConnection();
//2. 执行SQL语句
PreparedStatement ps = null;
ResultSet resultSet=null;
try {
ps = connection.prepareStatement("select * from employee");
//3. 处理结果集
resultSet = ps.executeQuery();
while(resultSet.next()){
int id = resultSet.getInt("eid");
String ename = resultSet.getString("ename");
int age = resultSet.getInt("age");
String sex = resultSet.getString("sex");
double salary = resultSet.getDouble("salary");
Date empdate = resultSet.getDate("empdate");
System.out.println(id+" : "+ename+" : "+age+" : "+sex+" : "+salary+" : "+empdate);
}
} catch (SQLException e) {
e.printStackTrace();
}finally {
//4. 关闭连接
JDBCUtils.close(connection,ps,resultSet);
}
}
}


浙公网安备 33010602011771号