一、XML 课程介绍
- XML 介绍与用途
- XML 语法规则
- XML 语义约束
- Java解析XML
- XPath 路径表达式
1. XML 介绍与用途
1. 什么是XML
XML全称是:可扩展标记语言,文件扩展名 .xml
2. XML与HTML的比较
- XML与HTML非常相似,都是编写标签
- XML没有预定义标签,HTML存在大量预定义标签
- XML重在保存和传输数据,HTML用于显示信息
3. XML的用途
- Java程序的配置描述文件
- 用于保存程序产生的数据
- 网络间的数据传输
2. XML文档结构
- 第一行必须是XML声明
- 有且只能有一个根节点
- XML标签的书写规则与HTML相同
1. XML声明
XML声明说明XML文档的基本信息,包括版本号与字符集,写在XML第一行。
<?xml version = "1.0" encoding = "UTF-8"?>
<!-- version 代表版本号
encoding UTF-8 设置字符集,用于支持中文
-->
<?xml version="1.0" encoding="utf-8" ?>
<!-- 人力资源管理系统 -->
<hr>
<employee no = "3309">
<name>张三</name>
<age>31</age>
<salary>4000</salary>
<department>
<dname>会计部</dname>
<address>XX大厦——B103</address>
</department>
</employee>
<employee no = "3310">
<name>李四</name>
<age>23</age>
<salary>3000</salary>
<department>
<dname>工程部</dname>
<address>XX大厦——B104</address>
</department>
</employee>
</hr>
3. XML标签书写规则
- 合法的标签名
- 适当的注释与缩进
- 合理使用属性
- 特殊字符与CDATA标签
- 有序的子元素
1. 合法的标签名
- 标签名要有意义
- 建议使用英文、小写字母,单词之间使用
-
分割 - 建议多级标签之间不要重名
2. 适当的注释与缩进
适当的注释和缩进可以使XML文档更容易阅读
3. 合理使用属性
- 标签属性用于描述标签不可或缺的信息
- 对标签分组或者问标签设置id时常用属性表示
4. 特殊字符与CDATA标签
标签体中,出现<
、>
特殊字符,会破坏文档结构
- 解决方案一:使用实体引入
- 解决方案二:使用CDATA标签
CDATA指的是不应由XML解析器进行解析的文本数据
从<![CDATA[
开始到]]>
结束
<?xml version="1.0" encoding="utf-8" ?>
<!-- HTML的课堂笔记,并不希望body中的文本被解析 -->
<lesson>
<content>
<![CDATA[
本节课我们学习HTML中a标签的使用:
<body>
<a href = "index.html">首页</a>
</body>
]]>
</content>
</lesson>
5. 有序的子元素
在XML多层嵌套的子元素中,标签前后顺序应该保持一致
4. XML语义约束
- XML文档结构正确,但可能无效
- 例如,员工档案XML中绝对不允许出现“植物品种”标签。XML语义约束就是用于规定XML文档中允许出现的哪些元素。
- XML语义约束的两种定义方式:
DTD
与XML Schema
1. DTD
A. DTD基本概念
- DTD是
文档类型定义
的缩写,是一种简单易用的语义约束方式。 - DTD通常以单独的文件出现,其拓展名为 .dtd
B. DTD定义节点
利用DTD中的<!ELEMENT>
标签,我们可以定义XML文档中允许出现的节点及数量,以hr.xml为例:
定义hr节点下只允许出现1个employee子节点
<!ELEMENT hr(employee)>
employee节点下必须包含四个节点,并且按顺序出现
<!ELEMENT employee (name,age,salary,department)>
定义name标签体只能是文本, #PCDATA代表文本元素
<!ELEMENT neme(#PCDATA)>
如某个节点需要多次重复出现,则需要子节点后增加相应的描述符+、*、?
。
hr节点下最少出现1个employee子节点
<!ELEMENT hr(employee+)>
hr节点下可出现0……n个employee子节点
<!ELEMENT hr(employee*)>
hr节点下最多出现1个employee子节点
<!ELEMENT hr(employee?)>
C. XML引用DTD文件
在XML中使用<!DOCTYPE>
标签来引用DTD文件
书写格式:
<!DOCTYPE 根节点 SYSTEM "dtd文件路径">
例子:
<!DOCTYPE hr SYSTEM "hr.dtd">
D. 创建DTD文件
hr.xml
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE hr SYSTEM "hr.dtd">
<!-- 人力资源管理系统 -->
<hr>
<employee no = "3309">
<name>张三</name>
<age>31</age>
<salary>4000</salary>
<department>
<dname>会计部</dname>
<address>XX大厦——B103</address>
</department>
</employee>
<employee no = "3310">
<name>李四</name>
<age>23</age>
<salary>3000</salary>
<department>
<dname>工程部</dname>
<address>XX大厦——B104</address>
</department>
</employee>
</hr>
hr.dtd
<?xml version="1.0" encoding="utf-8" ?>
<!ELEMENT hr (employee+)>
<!ELEMENT employee (name,age,salary,department)>
<!ATTLIST employee no CDATA "">
<!ELEMENT name (#PCDATA)>
<!ELEMENT age (#PCDATA)>
<!ELEMENT salary (#PCDATA)>
<!ELEMENT department (dname,address)>
<!ELEMENT dname (#PCDATA)>
<!ELEMENT address (#PCDATA)>
2. XML Schema
XML Schema基本概念
- XML Schema比DTD更为复杂,提供了更多功能
- XML Schema提供了数据类型、格式限定、数据范围等特性
- XML Schema是W3C标准
- XML Schema 文件扩展名为
.xsd
<?xml version="1.0" encoding="UTF-8"?>
<!-- 人力资源管理系统 -->
<hr xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLcation="hr.xsd">
<employee no = "3309">
<name>张三</name>
<age>31</age>
<salary>4000</salary>
<department>
<dname>会计部</dname>
<address>XX大厦——B103</address>
</department>
</employee>
<employee no = "3310">
<name>李四</name>
<age>23</age>
<salary>3000</salary>
<department>
<dname>工程部</dname>
<address>XX大厦——B104</address>
</department>
</employee>
</hr>
Schema代码:
<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema">
<element name="hr">
<!--complexType标签含义是复杂节点,包含子节点时,必须使用这个表签-->
<complexType>
<!--sequence标签是序列,含义是里面的子节点严格按照顺序编写-->
<sequence>
<element name = "employee" minOccurs="1" maxOccurs="10">
<complexType>
<sequence>
<element name = "name" type = "string"></element>
<element name = "age">
<simpleType>
<restriction base = "integer">
<minInclusive value="18"></minInclusive>
<maxInclusive value="60"></maxInclusive>
</restriction>
</simpleType>
</element>
<element name = "salary" type = "integer"></element>
<element name = "department">
<complexType>
<sequence>
<element name = "dname" type = "string"></element>
<element name = "address" type = "string"></element>
</sequence>
</complexType>
</element>
</sequence>
<attribute name = "no" type="string" use="required"></attribute>
</complexType>
</element>
</sequence>
</complexType>
</element>
</schema>
</schema>
5. Java解析XML
DOM文档对象模型
定义了访问和操作XML文档的标准方法,DOM把XML文档作为树结构查看,能够通过DOM树来读写所有元素。
A. Dom4j
- Dom4j是一个易用、开源的库,用于解析XML。
- Dom4j将XML视为Document对象。
- XML标签被Dom4j定义为Element(元素)对象。
B. Dom4j遍历XML
- 先下载Dom4j
- 在当前工程文件下新建一个lib文件夹,并将下载好的包拖进去
- 右键单击,选择“Build Path”
- 建立新的Java项目,代码:
import java.util.List;
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
public class HrReader {
public void readXml() {
String file = "C:\\Java\\eclipse\\eclipse-workspace\\Eclipse\\src\\com\\learn\\hr.xml";
// SAXReader 类是读取XML文件的核心类,用于将XML解析后以“树"的形式保存在内存中。
SAXReader reader = new SAXReader();
try {
Document document = reader.read(file);
//获取XML文档的根节点,即hr标签
Element root = document.getRootElement();
//elements方法用于获取指定的标签集合
List<Element> employees = root.elements("employee");
for (Element employee : employees) {
//Element方法用于获取唯一子节点对象
Element name = employee.element("name");
String empName = name.getText(); //getText()方法用于获取标签文本
System.out.println(empName);
//System.out.println("---------------");
System.out.println(employee.elementText("age")); //这是上面三行代码的简化
System.out.println(employee.elementText("salary"));
Element department = employee.element("department");
System.out.println(department.element("dname").getText());
System.out.println(department.element("address").getText());
Attribute att = employee.attribute("no");
System.out.println("编号:" + att.getText());
System.out.println("---------------------");
}
} catch (DocumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void main(String[] args) {
HrReader reader = new HrReader();
reader.readXml();
}
}
C. Dom4j更新XML
<?xml version="1.0" encoding="UTF-8"?>
<!-- 人力资源管理系统 -->
<hr>
<employee no="3309">
<name>张三</name>
<age>31</age>
<salary>4000</salary>
<department>
<dname>会计部</dname>
<address>XX大厦——B103</address>
</department>
</employee>
<employee no="3310">
<name>李四</name>
<age>23</age>
<salary>3000</salary>
<department>
<dname>工程部</dname>
<address>XX大厦——B104</address>
</department>
</employee>
<employee no="3311">
<name>李铁柱</name>
<age>37</age>
<salary>3600</salary>
<department>
<dname>人事部</dname>
<address>XX大厦-B105</address>
</department>
</employee>
</hr>
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
public class HrWriter {
public void writerXml() {
String file = "C:\\Java\\eclipse\\eclipse-workspace\\Eclipse\\src\\com\\learn\\hr.xml";
SAXReader reader = new SAXReader();
try {
Document document = reader.read(file);
Element root = document.getRootElement();
Element employee = root.addElement("employee"); //创建新的employee节点
employee.addAttribute("no", "3311");
Element name = employee.addElement("name");
name.setText("李铁柱");
employee.addElement("age").setText("37");
employee.addElement("salary").setText("3600");
Element department = employee.addElement("department");
department.addElement("dname").setText("人事部");
department.addElement("address").setText("XX大厦-B105");
//以上已经写入内存,但是还没有写入XML
Writer writer = new OutputStreamWriter(new FileOutputStream(file),"UTF-8");
document.write(writer);
writer.close();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void main(String[] args) {
HrWriter hrwriter = new HrWriter();
hrwriter.writerXml();
}
}
6. XPath表达式入门
- XPath路径表达式是XML文档中查找数据的语言。
- 掌握XPath可以极大的提高在提取数据时的开发效率。
- 学习XPath本质就是掌握各种形式表达式的使用技巧。
1. 最常用的基本表达式
表达式 | 描述 |
---|---|
nodename | 选取此节点的所有子节点 |
/ | 从根节点选取 |
// | 从匹配选择的当前节点选择文档中的节点,而从不考虑它们的位置 |
. | 选取当前节点 |
… | 选取当前节点的父节点 |
@ | 选取属性 |
例子:
路径表达式 | 结果 |
---|---|
bookstore | 选取bookstore节点的所有子节点 |
/bookstore | 选取根元素bookstore |
/bookstore/book | 选取属于bookstore的子元素的所有book元素 |
//book | 选取book子元素,而不考虑它在文档中的位置 |
bookstore//book | 选取属于bookstore元素的后代的所有book元素,而不考虑它们位于bookstore之下的什么位置 |
//@lang | 选取名为lang的所有属性 |
2. XPath谓语表达式
路径表达式 | 结果 |
---|---|
/bookstore/book[1] | 选取属于bookstore子元素的第一个book元素 |
/bookstore/book[last()] | 选取属于bookstore子元素的最后一个book元素 |
/bookstore/book[last()-1] | 选取属于bookstore子元素的倒数第二个book元素 |
/bookstore/book[position() < 3] | 选取最前面的两个属于bookstore元素的子元素的book元素 |
//title[@lang] | 选取所有拥有lang属性的title元素 |
//title[@lang=‘eng’] | 选取所有title元素,并且将这些元素拥有值为eng的lang属性 |
bookstore/book[price > 35.00] | 选取bookstore元素的所有book元素,且其中的price元素的值必须大于35.00 |
bookstore/book[price > 35.00] /title | 选取bookstore元素中的book元素的所有所有title元素,且其中的price元素的值必须大于35 |
3. XPath实验室
利用Dom4j开发“XPath”实验室。
- Jaxen是一个Java编写的开源的XPath库。这是适应多种不同的对象模型,包括DOM、XOM、Dom4j和JDOM。
- Dom4j底层依赖Jaxen实现XPath查询
- Jaxen下载地址:https://developer.aliyun.com/mvn/search