XML学习笔记
作者水平有限,如有错误还请指正!
1.XML
1.1 xml简介
- xml, eXtensible Markup Language, 可扩展标记语言。(标记语言,类HTML)
- xml是非常灵活的语言,没有固定的标签,所有的标签都可以自定义。
- 通常,xml被用于信息的记录和传递。因此,xml经常被用于充当配置文件。
1.2 XML与HTML的比较
- HTML用于显示数据,XML用于传输和存储数据。
- HTML标签不区分大小写,XML标签严格区分大小写。
- HTML有多个根元素,二格式良好的XML有且只有一个根元素。
- HTML中空格是自动过滤的,XML中空格不会自动过滤。
- HTML中的标签时预定义的标签,二XML中的标签可以根据需要自己定义,并且可以扩展。
1.3 XML语法
-
文档声明
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
- version:用于指定遵循XML规范的版本号。
- encoding:用于指定XML文件使用的编码集。
- standalone:指定XML文件是否与一个外部文档嵌套使用,取值为yes或no。
-
元素定义
<元素名>元素内容</元素名>
-
属性定义
<元素名 元素属性=“属性值”></元素名>
-
注释
-
一个格式良好的xml文件
<?xml version="1.0" encoding="UTF-8"> <书架> <书> <书名>java基础案例分析</书名> <作者>刘犇</作者> <售价>45.00元</售价> </书> <书> <书名>XML通识</书名> <作者>蒋璨</作者> <售价>12.00元</售价> </书> </书架>
2. DTD
2.1 DTD简介
- DTD,Document Type Definition,文档类型定义
- DTD用于约束xml的文档格式,保证xml是一个有效的xml。
- DTD可分为两种,内部DTD和外部DTD
2.2 使用DTD
内部DTD的声明语法
<!DOCTYPE 根元素 [元素声明]>
-
带有DTD约束的XML文档实例
<?xml version="1.0"?> <!DOCTYPE note [ <!ELEMENT note (to,from,heading,body)> <!ELEMENT to (#PCDATA)> <!ELEMENT from (#PCDATA)> <!ELEMENT heading (#PCDATA)> <!ELEMENT body (#PCDATA)> ]> <note> <to>George</to> <from>John</from> <heading>Reminder</heading> <body>Don't forget the meeting!</body> </note>
-
以上代码段的解释
!DOCTYPE note (第二行)定义此文档是 note 类型的文档。
!ELEMENT note (第三行)定义 note 元素有四个元素:“to、from、heading,、body”
!ELEMENT to (第四行)定义 to 元素为 “#PCDATA” 类型
!ELEMENT from (第五行)定义 from 元素为 “#PCDATA” 类型
!ELEMENT heading (第六行)定义 heading 元素为 “#PCDATA” 类型
!ELEMENT body (第七行)定义 body 元素为 “#PCDATA” 类型
外部DTD文档声明
<!DOCTYPE 根元素 SYSTEM "文件名">
-
与上面的XML文档相同,但拥有一个外部的DTD文档(类似于HTML文档中使用link标签引用CSS文件)
<?xml version="1.0"?> <!DOCTYPE note SYSTEM "note.dtd"> <note> <to>George</to> <from>John</from> <heading>Reminder</heading> <body>Don't forget the meeting!</body> </note>
-
外部的DTD文档(note.dtd)
<!ELEMENT note (to,from,heading,body)> <!ELEMENT to (#PCDATA)> <!ELEMENT from (#PCDATA)> <!ELEMENT heading (#PCDATA)> <!ELEMENT body (#PCDATA)>
2.3 DTD 的语法
DTD的声明
-
声明一个元素
<!ELEMENT 元素名称 类别> <!-- 或 --> <!ELEMENT 元素名称 (元素内容)>
-
空元素
<!ELEMENT 元素名称 EMPTY>
-
带有任何内容的元素
<!ELEMENT 元素名称 ANY>
-
带有子元素(序列)的元素
<!ELEMENT 元素名称 (子元素名称 1)> <!-- 或 --> <!ELEMENT 元素名称 (子元素名称 1,子元素名称 2,.....)>
-
声明至少出现一次的元素
<!ELEMENT 元素名称 (子元素名称+)>
-
出现零次或多次
<!ELEMENT 元素名称 (子元素名称?)>
-
声明“非……/即……”类型的内容
<!ELEMENT note (to,from,header,(message|body))> <!-- "note" 元素必须包含 "to" 元素、"from" 元素、"header" 元素,以及非 "message" 元素既 "body" 元素。 -->
-
声明混合型内容
<!ELEMENT note (#PCDATA|to|from|header|message)*>
DTD的属性
-
声明语法
<!ATTLIST 元素名称 属性名称 属性类型 默认值>
-
属性类型选项
类型 描述 CDATA 值为字符数据 (character data) (en1|en2|…) 此值是枚举列表中的一个值 ID 值为唯一的 id IDREF 值为另外一个元素的 id IDREFS 值为其他 id 的列表 NMTOKEN 值为合法的 XML 名称 NMTOKENS 值为合法的 XML 名称的列表 ENTITY 值是一个实体 ENTITIES 值是一个实体列表 NOTATION 此值是符号的名称 xml: 值是一个预定义的 XML 值 -
默认值参数
值 解释 值 属性的默认值 #REQUIRED 属性值是必需的 #IMPLIED 属性不是必需的 #FIXED value 属性值是固定的
2.4 DTD实体
-
DTD实体是用于定义引用普通文本或特殊字符的快捷方式的变量。
-
实体引用是对实体的引用。
-
实体可在内部或外部进行声明。
-
外部实体的声明
<!ENTITY 实体名称 SYSTEM "URI/URL">
-
内部实体的声明
<!ENTITY 实体名称 "实体的值"> <!-- 一个实体由三部分构成: 一个和号 (&), 一个实体名称, 以及一个分号 (;)。-->
-
3. XML的解析技术
- 对XML文件进行操作,包括创建XML,对XML文件进行增删改查操作。
3.1 常见的解析技术
-
DOM解析
官方提供的解析方式,基于xml树解析的,比较耗费资源,适用于频繁访问xml
-
SAX解析
民间的解析方式,基于事件的解析,消耗资源小,适用于数量较大的xml
-
JDOM解析
开放源代码,比DOM更快,JDOM仅适用于具体类而不适用接口
-
DOM4J
开放源代码,非常优秀的Java XML API,性能优异、功能强大,使用接口实现而不是实现类
3.2 DOM4J 解析XML文件
- 读取xml文件中的信息
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-I96E0KJs-1646959595367)(C:\Users\34162\AppData\Roaming\Typora\typora-user-images\image-20220310193204859.png)]
- 获取根元素
- 获取根元素的所有子元素
- 迭代子元素
实例:
book.xml
<?xml version="1.0" encoding="UTF-8"?>
<books>
<book id = "1">
<name>《称帝秘籍》</name>
<price>50</price>
<author>刘备</author>
</book>
<book id = "2">
<name>《称帝秘籍2》</name>
<price>52</price>
<author>刘备</author>
</book>
</books>
testReaderXML.java
package com.Etui1.testXML;
import java.io.File;
import java.util.Iterator;
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.junit.Test;
public class testReaderXML {
@Test
public void test1() throws Exception {
SAXReader saxReader = new SAXReader();
Document read = saxReader.read(new File("src/book.xml"));
Element rootElement = read.getRootElement();
//获取根元素下的所有子元素
Iterator<?> it = rootElement.elementIterator();
while(it.hasNext()) {
// 取出元素
Element e = (Element) it.next();
// 获取id属性
Attribute id = e.attribute("id");
System.out.println(id.getName() + "=" + id.getValue());
// 获取books的子元素
Element name = e.element("name");
Element price = e.element("price");
Element author = e.element("author");
// 打印
System.out.println(name.getName() + "=" + name.getText());
System.out.println(price.getName() + "=" + Double.parseDouble(price.getText()));
System.out.println(author.getName() + "=" + author.getText());
}
}
}
运行结果:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5Uw9Sne9-1646959595368)(C:\Users\34162\AppData\Roaming\Typora\typora-user-images\image-20220310193457318.png)]
3.3 DOM4J生成xml文件
- 通过DocumentHelper生成Document对象
- 给Document对象添加根元素(document.addElement("");),Element对象
- 为根元素添加子元素
- 为元素添加属性(<元素名>.addAttribute("<属性名>","<属性值>"))
- 为元素添加文本(<元素名>.addText("<文本内容>"))
实验案例:
testXml2.java
package com.Etui1.testXML;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.XMLWriter;
public class TestXml2 {
public static void main(String[] args) throws IOException {
// 1、通过DocumentHelper生成一个Document对象
Document doc = DocumentHelper.createDocument();
// 2、添加并得到根元素
Element root = doc.addElement("books");
// 3、为根元素添加子元素
Element book = root.addElement("book");
// 4、为book元素添加属性
book.addAttribute("id", "b1");
// 5、为book添加子元素
Element name = book.addElement("name");
Element price = book.addElement("price");
Element author = book.addElement("author");
// 6、为子元素添加文本
name.addText("《JavaScript忍者秘籍》");
price.addText("88");
author.addText("John Resig");
// // 7、将doc输出到xml文件中
// Writer writer = new OutputStreamWriter(new FileOutputStream("src/book2.xml"), "UTF-8");
// doc.write(writer);
// // 8、关闭资源
// writer.close();
// 格式良好的输出
OutputFormat format = OutputFormat.createPrettyPrint();
XMLWriter writer = new XMLWriter(new OutputStreamWriter(new FileOutputStream("src/book2.xml"), "UTF-8"), format);
writer.write(doc);
// 8、关闭资源
writer.close();
}
}
运行结果:
文件结构: