首先说明,这个是自己学习过程中的笔记。希望对各位有所帮助!
XML
- XML介绍与用途
- XML的全称是EXtensible Markup Language,可扩展标记语言
- 编写XML就是编写标签,与HTML非常相似,扩展名.xml
- 良好的人机可读性
xml hr.xml <employee> <name> 张三 </name> <age> 31 </age> <height> 178 </height> </employee>
- XML的用途
- Java程序的配置描述文件
- 用于保存程序产生的数据
- 网络间数据传输
- XML文档结构
- 第一行必须是XML声明
- XML声明说明XML文档的基本信息,包括版本号与字符集,写在XML第一行
- 有且只有一个根节点
- XML标签的书写规则与HTML相同
- XML标签书写规则
- 合法的标签名
- 标签名要有意义
- 建议使用英文,小写字母,单词之间使用“-”分割
- 建议多级标签之间不要存在重名的情况
<abd> adc </abc> <考试$></考试$>
- 合理使用属性
- 标签属性用于描述标签不可或缺的信息
- 对标签分组或者为标签设置Id时常用属性表示
- 标签中唯一的身份信息放在属性中
<shop-cart> <item sn="771921" category="电器"> <name>xx空调</name> <price>2000.00</price> <num>1</num> </item> </shop-cart>
- 有序的子元素
- 在XML多层嵌套的子元素中,标签前后顺序应保持一致
- 适当的注释与缩进
- 特殊字符与CDATA标签
- 标签体中,出现“<” ">"特殊字符,会破坏文档结构
<exam> <question>1 + 4 < 3是否正确?</question> </exam> 解决办法 1.使用实体引用 2.使用CDATA标签 CDATA指的是不应由XML解析器进行解析的文本数据 从"<![CDATA["开始,到"]]>"结束
-
- XML支持五种实体应用(实体引用后面有个分号)
| 实体引用 | 对应符号 | 说明 | | -------- | -------- | ------ | | < | < | 小于 | | > | > | 大于 | | & | & | 相和 | | &apos | ' | 单引号 | | " | " | 双引号 |
- 练习:编写xml文档plan.xml,进行教学计划中课程信息的存储
xml <?xml version="1.0" encoding="UTF-8"?> <teaching-plan> <course> <course-name>大学英语</course-name> <class-hour>36</class-hour> <exam-form>考试</exam-form> </course> <course> <course-name>高等数学</course-name> <class-hour>70</class-hour> <exam-form>考试</exam-form> </course> <course> <course-name>计算机应用基础</course-name> <class-hour>108</class-hour> <exam-form>上机考试</exam-form> </course> </teaching-plan>
XML语义约束
- XML文档结构正确,但可能不是有效的
- 例如,员工档案XML中绝不允许出现“植物品种”标签。XML语义约束就是用于规定XML文档中允许出现哪些元素
- XML语义约束有两种定义方式:DTD与XML Schema
- Document Type Definition
- 文档类型定义,是一种简单易用的语义约束方式
- DTD文件的扩展名为.dtd
hr.dtd <!ELEMENT hr (employee+)>
-
- DTD定义节点
- 利用DTD中的
<!ELEMENT>
标签,我们可以定义XML文档中允许出现的节点及数量,以hr.xml为例:定义hr节点下只允许出现1个employee子节点 <!ELEMENT hr (employee)> employee节点下必须包含以下四个节点,且按顺序出现 <!ELEMENT employee(name, age, salary, department)> 定义name标签体只能是文本,#PCDATA代表文本元素 <!ELEMENT name(#PCDATA)>
- DTD定义节点数量
- 如某个子节点需要多次重复出现,则需要在子节点之后增加相应的描述符
定义hr节点下最少出现1个employee子节点 <!ELEMENT hr (employee+)> 定义hr节点下出现0..N个employee子节点 <!ELEMENT hr (employee*)> 定义hr节点下最多出现1个employee子节点 <!ELEMENT hr (employee?)>
-
- XML应用DTD文件
- 在XML中使用
<!DOCTYPE>
标签来引用DTD文件
书写格式: <!DOTYPE 根节点 SYSTEM "dtd文件路径"> 示例: <!DOCTYPE hr SYSTEM "hr.dtd">
- 练习
``` <?xml version="1.0" encoding="UTF-8"?> <!ELEMENT teaching-plan (course+)> <!ELEMENT course (course-name,class-hour,exam-form)> <!ELEMENT course-name (#PCDATA)> <!ELEMENT class-hour (#PCDATA)> <!ELEMENT exam-form (#PCDATA)>
```
- XML Schema
xml <?xml version="1.0" encoding="UTF-8"?> <teaching-plan xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="teach.xsd"> <course id="1"> <course-name>大学英语</course-name> <class-hour>36</class-hour> <exam-form>考试</exam-form> </course> <course id="2"> <course-name>高等数学</course-name> <class-hour>70</class-hour> <exam-form>考试</exam-form> </course> <course id="3"> <course-name>计算机应用基础</course-name> <class-hour>108</class-hour> <exam-form>上机考试</exam-form> </course> </teaching-plan>
```scheme <?xml version="1.0" encoding="UTF-8"?>
```
DOM文对象模型
- DOM(document object model)定义了访问和操作XML文档的标准方法,DOM吧XML文档作为树结构来查看,能够通过DOM树来读写所有元素
- Dom4j
- Dom4j是一个易用的、开源的库,用于解析XML。它应用于Java平台,具有性能优异、功能强大和及其易使用的特点
- Dom4j将XML视为Document对象
- XML标签Dom4j定义为Element对象
```java // Dom4j对XML进行读取操作 package com.imooc.dom4j;
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 HrReaderTest { public void readXml() { String file = "d:/downloads/xml/xml/src/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");
// getText方法用于获取标签文本
String empName = name.getText();
System.out.println(empName);
System.out.println(employee.elementText("age"));
System.out.println(employee.elementText("salary"));
Element department = employee.element("department");
System.out.println(department.elementText("dname"));
System.out.println(department.elementText("address"));
Attribute att = employee.attribute("no");
System.out.println(att.getText());
}
} catch (DocumentException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
}
public static void main(String[] args) {
HrReaderTest hr = new HrReaderTest();
hr.readXml();
}
}
```
- 利用Dom4j更新XML
```java package com.imooc.dom4j;
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 HrWriteTest { public void writeXml() { String file = "d:/downloads/xml/xml/src/hr.xml"; SAXReader reader = new SAXReader();
try {
Document document = reader.read(file);
Element root = document.getRootElement();
Element employee = root.addElement("employee");
employee.addAttribute("no", "3322");
Element name = employee.addElement("name");
name.setText("Alice");
employee.addElement("age").setText("34");
employee.addElement("salary").setText("6000");
Element department = employee.addElement("department");
department.addElement("dname").setText("IT部");
department.addElement("address").setText("XX大厦A-303");
Writer writer = new OutputStreamWriter(new FileOutputStream(file), "utf-8");
document.write(writer);
writer.close();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
// TODO 自动生成的方法存根
HrWriteTest hr = new HrWriteTest();
hr.writeXml();
}
}
```
Xpath路径表达式
- Xpath路径表达式是XML文档中查找数据的语言
- 掌握XPath可以极大的提高在提取数据时的开发效率
- 学习XPath本质就是掌握各种形式表达式的使用技巧
- 最常见的基本表达式
| 表达式 | 描述 | | -------- | -------------------------------------------------------- | | nodename | 选取此节点的所有子节点 | | / | 从根节点选取 | | // | 从匹配选择的当前节点选择文档中的节点,而不考虑他们的位置 | | . | 选取当前节点 | | .. | 选取当前节点的父节点 | | @ | 选取属性 |
- 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.00 |