一、XML
1. 概述
XML的全称为(eXtensible Markup Language),是一种可扩展的标记语言。
- 标记语言:通过标签来描述数据的一门语言。
- 可扩展:标签的名字是可以自定义的。
作用:
1.XML 的设计宗旨是传输数据。XML作用是用于保存数据。
2.不同的计算机语言之间,不同的操作系统之间进行数据交换。
3.各种框架的配置文件
2. Xml语法规则
2.1 文档声明
XML文件的后缀名为:xml
文档声明必须是XML第一行
<?xml version="1.0" encoding="UTF-8" ?>
version:版本号,该属性是必须存在的
encoding:文件编码,该属性不是必须的(一般取值都是UTF-8)
文档声明的作用是声明这个文件内容是一个XML
2.2 标签和属性
标签也称为元素
标签由一对尖括号和合法标识符组成
标签必须成对出现
特殊的标签可以不成对,但是必须有结束标记
标签中可以定义属性,属性和标签名空格隔开
属性值必须用引号引起来
标签需要正确的嵌套
2.3 根标签
处于xml文件最外层的,没有被其他标签包裹的就称为根标签。
在一个XML文档中,只允许有一个根标签。
2.4 注释
注释语法格式
<!-- 注释内容 -->
注意:在XML中注释不能嵌套
2.5 实体字符/转义字符
因为很多符号已经被XML所使用,所以在元素体或属性值中想使用这些符号就必须使用实体字符
规律所有的实体字符都是以**&开头, 以;**结尾
说明 | 字符 | 转义字符 |
---|---|---|
小于 | < | & lt; |
大于 | < | & gt; |
双引号 | " | & quot; |
单引号 | ’ | & apos; |
与符号 | & | & amp; |
2.6 字符数据区
CDATA 字符数据区的作用:放在CDATA字符数据区中的数据,作为纯文本解析,原样显示
放在CDATA字符数据区中的数据,作为纯文本解析,原样显示
快捷键:CD
<?xml version="1.0" encoding="UTF-8" ?><!-- 文档声明 -->
<!-- 根标签在最外层,只能有一个 -->
<persons>
<person id="1">
<name>李四</name>
<age>18</age>
<score>19</score>
<books>
<!-- 相当于<Java编程思想> 转义字符-->
<Java编程思想>
<!-- 字符数据区(快捷键CD) -->
<![CDATA[
<php>
]]>
</books>
</person>
</persons>
3. Xml约束
因为XML文件的标签和属性可以随意扩展,通过XML约束来限定XML文件中可使用的标签以及属性。
XML的两种约束
DTD约束,比较简单,功能相对弱
Schema,比较复杂,功能相对强
3.1 DTD语法约束
导入DTD文件的两种格式 | 说明 |
---|---|
< !DOCTYPE 根元素 SYSTEM “DTD文件路径”> | 引入本地的dtd约束 |
< !DOCTYPE 根元素 PUBLIC “文件描述” “DTD文件路径”> | 引入网络的dtd约束 |
3.1.1 本地dtd约束
<!-- 根标签 books 可以有多个book标签 -->
<!ELEMENT books (book+)>
<!-- book标签内可以有 name、price、author 只能出现一次 -->
<!ELEMENT book (name,price,author)>
<!-- name标签内只能输入字符串 -->
<!ELEMENT name (#PCDATA)>
<!ELEMENT price (#PCDATA)>
<!ELEMENT author (#PCDATA)>
<?xml version="1.0" encoding="UTF-8" ?>
<!-- 引入本地dtd约束 -->
<!DOCTYPE books SYSTEM "book.dtd">
<books>
<book>
<name>Java编程思想</name>
<price>69</price>
<author>埃克尔</author>
</book>
</books>
3.1.2 网络dtd约束(例如mybites)
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC
"-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
3.2 Schema约束
Schema约束文件扩展名(XML Schema Definition)XML模式定义:xsd
Schema 功能更强大,数据类型约束更完善
Schema文件本身也是XML文件,所以也有根元素,根元素的名字叫:schema
一个XML中可以引用多个Schema约束文件
<?xml version="1.0" encoding="UTF-8" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.itcast.cn/"
elementFormDefault="qualified">
<xs:element name='书架'>
<xs:complexType>
<xs:sequence maxOccurs='unbounded'>
<xs:element name='书'>
<xs:complexType>
<xs:sequence>
<xs:element name='书名' type='xs:string'/>
<xs:element name='作者' type='xs:string'/>
<xs:element name='售价' type='xs:double'/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
3.2.1 导入格式
<根标签
xmlns="命名空间"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="命名空间 schema约束文件名">
<!-- 编写XML元素 -->
</根标签>
<?xml version="1.0" encoding="utf-8" ?>
<书架
xmlns="http://www.itcast.cn/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.itcast.cn/ books.xsd">
<!-- 编写XML元素 -->
<书>
<书名>Java编程思想</书名>
<作者>埃克尔</作者>
<售价>39.9</售价>
</书>
</书架>
二、 Dom4j
1. Xml解析介绍
什么是XML的解析,使用程序读取XML中的数据。
两种解析方式:
1.SAX解析
2.DOM解析
2. 常见解析工具
名称 | 说明 |
---|---|
JAXP | SUN公司提供的一套XML的解析的API |
JDOM | JDOM是一个开源项目,它基于树型结构,利用纯JAVA的技术对XML文档实现解析、生成、序列化以及多种操作。 |
dom4j | 是JDOM的升级品,用来读写XML文件的。具有性能优异、功能强大和极其易使用的特点,它的性能超过sun公司官方的dom 技术,同时它也是一个开放源代码的软件,Hibernate也用它来读写配置文件。 |
jsoup | 功能强大DOM方式的XML解析开发包,尤其对HTML解析更加方便 |
2.1 DOM解析
2.1.1 Dom4j下载和导入
- 下载
Dom4j官网地址: http://www.dom4j.org/ - 导入
1.在项目中创建一个文件夹:lib
2.将dom4j-2.1.1.jar文件复制到 lib 文件夹
3.在jar文件上点右键,选择 Add as Library -> 点击OK
4.在类中导包使用
2.1.2 Dom4j解析XML:获取Document对象
SAXReader方法
方法名 | 说明 |
---|---|
SAXReader() | 构造方法,创建解析器 |
Document read(File file) | 读取XML文档,生成Document对象 |
Document的方法
方法名 | 说明 |
---|---|
Element getRootElement() | 获得根元素 |
2.1.3 Dom4j解析XML- Element对象
一个Element对象,表示XML中的一个标签
Element类的方法
方法名 | 说明 |
---|---|
List elements() | 得到当前元素下所有子元素 |
List elements(String name) | 得到当前元素下指定名字的子元素返回集合 |
Element element(String name) | 得到当前元素下指定名字的子元素,如果有很多名字相同的返回第一个 |
String getName() | 得到元素名字 |
String attributeValue(String name) | 通过属性名直接得到属性值 |
String getText() | 得到当前标签的文本 |
2.2 Xml解析案例
2.2.1 需求
利用Dom4J的知识,将userList.xml文件中的联系人数据封装成List集合,其中每个元素是实体类User 。打印输出 List 中的每个元素。
2.2.2 分析
1.导入dom4j解析的依赖jar包
2.创建解析对象 SAXReader sax = new SAXReader();
3.用解析对象去读取xml文档,获取dom
Document document = sax.read(new File(“xml路径”));
4.获取根标签 Element root = document.getRootElement();
5.获取根标签下面符合要求的所有子标签集合 List users = root.elements(“user”);
6.遍历集合获取每一个符合的子标签内的内容 Element value = user.element(“value”).getText();
7.创建Person对象,封装无参数、有参构造方法、get、set方法、toString()方法。
8.每次获取到的所有值new Peson()对象添加入集合中。
9.遍历打印。
2.2.3 实现
提示:需要先导入dom4j 的jar包
<?xml version="1.0" encoding="UTF-8"?>
<userList>
<user id="1">
<name>潘金莲</name>
<gender>女</gender>
<email>panpan@itcast.cn</email>
</user>
<user id="2">
<name>武松</name>
<gender>男</gender>
<email>wusong@itcast.cn</email>
</user>
<user id="3">
<name>武大狼</name>
<gender>男</gender>
<email>wuda@itcast.cn</email>
</user>
</userList>
User.java
package com.hntou.parsing;
public class User {
private int id;
private String name;
private String gender;
private String email;
public User() {
}
public User(int id, String name, String gender, String email) {
this.id = id;
this.name = name;
this.gender = gender;
this.email = email;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
@Override
public String toString() {
return "Person{" +
"id=" + id +
", name='" + name + '\'' +
", gender='" + gender + '\'' +
", email='" + email + '\'' +
'}';
}
}
demo01.java
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
public class demo01 {
public static void main(String[] rgs) throws Exception {
//1.导入dom4j解析的依赖和jar包
//2.创建解析对象 SAXReader() IO流
SAXReader sax = new SAXReader();
Document document = sax.read(new File("day_14/XML/userList.xml"));
//3.操作Document,获取Element对象
Element root = document.getRootElement();
/**
* 根据根标签获取子标签
*/
//获取所有user子标签 <user>
List<Element> userList = root.elements("user");
//获取所有的子标签
List<Element> list = root.elements();
/**
* 获取xml所有数据 封装为User对象 再存入集合
*/
List<Element> users = root.elements("user");
ArrayList<User> usersList = new ArrayList<>();
for (Element user : users) {
/**
* 获取每个user的标签内容
*/
usersList.add(new User(
Integer.parseInt(user.attributeValue("id")),
user.element("name").getText(),
user.element("gender").getText(),
user.element("email").getText()));
}
/**
* 遍历list集合打印
*/
for (User user : usersList) {
System.out.println(user);
}
}
}
2.3 Xpath(路径解析)
根据结点去解析,如果层数过多就非常的繁琐。
XPath使用路径表达式来选取XML文档中的元素节点或属性节点。节点是通过沿着路径 (path) 来选取的。XPath在
解析XML文档方面提供了一独树一帜的路径思想。
/元素/子元素/孙元素
//子元素//孙元素
除了dom4j的jar包还需要加入jaxen的jar包
2.3.1 XPath使用步骤
步骤1:导入jar包 (dom4j 和 jaxen-1.1.2.jar )(重要)。
步骤2:通过dom4j的SAXReader获取Document对象。
步骤3: 利用XPath提供的API,结合XPath的语法完成选取XML文档元素节点进行解析操作。
方法名 | 说明 |
---|---|
Node selectSingleNode(“XPath表达式”) | 获取符合表达式的唯一元素 |
List selectNodes(“XPath表达式”) | 获取符合表达式的元素集合 |
2.3.2 Xpath绝对路径
路径表达式 | 说明 |
---|---|
/根元素/子元素/孙元素 | 从根元素开始,一级一级向下查找,不能跨级 |
读取 素材的 xpath_userList.xml 文件。
<?xml version="1.0" encoding="UTF-8"?>
<userList>
<user id="1" vip="false">
<name>潘金莲</name>
<gender>女</gender>
<email>panpan@itcast.cn</email>
</user>
<user id="2" vip="false">
<name>武松</name>
<gender>男</gender>
<email>wusong@itcast.cn</email>
<brother>
<name>武大郎</name>
</brother>
</user>
<user id="3" vip="true">
<name>西门庆</name>
<gender>男</gender>
<email>xmq@itcast.cn</email>
</user>
<name id="4" vip="true">法外狂徒张三</name>
</userList>
采用绝对路径从根节点开始逐层的查找 /userList/user/name 路径下的所有name标签
public class demo02 {
public static void main(String[] args) throws Exception{
//1.读取文件
SAXReader sax = new SAXReader();
Document document = sax.read(new File("day_14/XML/xpath_userList.xml"));
//2.绝对路径查找 所有user下的name
List<Node> nodesName = document.selectNodes("/userList/user/name");
for (Node node : nodesName) {
System.out.println(node.getText());
}
}
}
步骤:
1.读取 XML 文档并获得Document对象。
2.定义 XPath 表达式:/userList /user/name
3.调用Document对象的 selectNodes(“表达式”) 方法执行XPath获得Node集合。
4.遍历输出每个节点。
2.3.3 Xpath相对路径
路径表达式 | 说明 |
---|---|
./子元素/孙元素 | 从当前元素开始,一级一级向下查找,不能跨级 |
读取 素材的 xpath_userList.xml 文件。
使用相对路径读取 user 标签下的直接子标签 name,输出姓名
1.获得根节点对象 userList.
2.相对路径表达式: ./user/name
3.通过根节点对象调用 selectNodes(表达式) 方法。获取所有节点。
4.打印输出所有的name节点的文本。
/**
* 相对路径
*/
public class demo03 {
public static void main(String[] args) throws Exception {
SAXReader sax = new SAXReader();
Document document = sax.read(new File("day_14/XML/xpath_userList.xml"));
Element userList = document.getRootElement();
List<Node> nodes = userList.selectNodes("./user/name");
for (Node node : nodes) {
System.out.println(node.getText());
}
}
}
2.3.4 Xpath全文搜索
路径表达式 | 说明 |
---|---|
//name | 整个xml中查找所有name元素,无论标签在哪一级 |
//user/name | 全文查找所有的user下的name标签。(name必须是user的直接子标签) |
//user//name | user无论在哪一级,name只要是user的子孙元素都可以找到 |
直接全文搜索所有的name元素,并打印文本值
1.创建XPath表达式: //name
2.使用 selectNodes(表达式) 方法查询所有的name节点。
3.输出name节点的文本值(姓名)。
import java.io.File;
import java.util.List;
/**
* 全文搜索
*/
public class demo04 {
public static void main(String[] args) throws Exception{
SAXReader sax = new SAXReader();
Document document = sax.read(new File("day_14/XML/xpath_userList.xml"));
List<Node> nodes = document.selectNodes("//name");
for (Node node : nodes) {
System.out.println(node.getText());
}
}
}
2.3.4 Xpath属性查找
表达式 | 说明 |
---|---|
//*[@属性名] | 全文查找任意元素,只要包含指定属性名即可。(*表示匹配任意元素) |
//元素[@属性名] | 全文查找指定元素,并且元素要有指定属性名 |
//元素//[@属性名=‘值’] | 全文查找指定元素,并且属性名等于给定值 |
1.读取 素材的 xpath_userList.xml 文件。
2.查找所有包含id属性的元素。
3.查找所有包含id属性的user元素。
4.查询所有vip属性值为true的user元素。
import org.dom4j.Document;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;
import java.io.File;
import java.util.List;
/**
* 属性搜索 @属性(前面一定要有标签)
*/
public class demo05 {
public static void main(String[] args) throws Exception{
SAXReader sax = new SAXReader();
Document document = sax.read(new File("day_14/XML/xpath_userList.xml"));
//所有包括id属性的元素 (这里拿到到是user标签 打印出来文本是空格)
List<Node> nodes1 = document.selectNodes("//*[@id]");
//查找包括id属性的user元素
List<Node> nodes2 = document.selectNodes("//user[@id]");
//查询所有vip属性值为true的user元素
List<Node> nodes3 = document.selectNodes("//user[@vip='true']");
}
}
三、总结
一、xml约束
1.DTD约束:比较简单,功能相对弱,不能约束自己。
2.Schema约束:比较复杂,功能相对强,可以约束自己。
二、xml文件传统解析步骤
1.导入dom4j解析的依赖jar包
2.创建解析对象 SAXReader sax = new SAXReader();
3.用解析对象去读取xml文档,获取dom
Document document = sax.read(new File(“xml路径”));
4.获取根标签 Element root = document.getRootElement();
5.获取到跟标签之后就可以用Elemnts()获取到所有的子标签,每一个Elemnt再通过getText()去获取标签内的属性。
三、Xpath(路径解析)
1.绝对路径
2.相对路径
3.全文搜索
4.属性查找