- XML命名空间和dom4j解析技术
2.★XML命名空间
- XML 命名空间提供避免元素命名冲突的方法。
2.1 命名冲突
在 XML 中,元素名称是由开发者定义的,当两个不同的文档使用相同的元素名时,就会发生命名冲突。例如
这个 XML 携带 HTML 表格的信息:
1
2
3
4
5
6<table>
<tr>
<td>Apples</td>
<td>Bananas</td>
</tr>
</table>这个 XML 文档携带有关桌子的信息(一件家具):
1
2
3
4
5<table>
<name>African Coffee Table</name>
<width>80</width>
<length>120</length>
</table>
假如这两个 XML 文档被一起使用,由于两个文档都包含带有不同内容和定义的
元素,就会发生命名冲突。
XML 解析器无法确定如何处理这类冲突。
2.2 使用前缀来避免命名冲突
在 XML 中的命名冲突可以通过使用名称前缀从而容易地避免。例如:
该 XML 携带某个 HTML 表格和某件家具的信息:
1
2
3
4
5
6
7
8
9
10
11
12<h:table>
<h:tr>
<h:td>Apples</h:td>
<h:td>Bananas</h:td>
</h:tr>
</h:table>
<f:table>
<f:name>African Coffee Table</f:name>
<f:width>80</f:width>
<f:length>120</f:length>
</f:table>在上面的实例中,不会有冲突,因为两个
元素有不同的名称。
2.3 XML 命名空间 - xmlns 属性
当在 XML 中使用前缀时,一个所谓的用于前缀的命名空间必须被定义。
命名空间是在元素的开始标签的 xmlns 属性中定义的。例如:
1
2
3
4
5
6
7
8
9
10
11
12
13
14<root>
<h:table xmlns:h="http://www.w3.org/TR/html4/">
<h:tr>
<h:td>Apples</h:td>
<h:td>Bananas</h:td>
</h:tr>
</h:table>
<f:table xmlns:f="http://www.w3cschool.cc/furniture">
<f:name>African Coffee Table</f:name>
<f:width>80</f:width>
<f:length>120</f:length>
</f:table>
</root>命名空间声明的语法如下:
xmlns:前缀="URI"
。在上面的实例中,
标签的 xmlns 属性定义了
h:
和f:
前缀的合格命名空间。当命名空间被定义在元素的开始标签中时,所有带有相同前缀的子元素都会与同一个命名空间相关联。
命名空间也可以在 XML 根元素中声明(用得较多):
1
2
3
4
5
6
7
8
9
10
11
12
13
14<root xmlns:h="http://www.w3.org/TR/html4/"
xmlns:f="http://www.w3cschool.cc/furniture">
<h:table>
<h:tr>
<h:td>Apples</h:td>
<h:td>Bananas</h:td>
</h:tr>
</h:table>
<f:table>
<f:name>African Coffee Table</f:name>
<f:width>80</f:width>
<f:length>120</f:length>
</f:table>
</root>注意:命名空间 URI 不会被解析器用于查找信息。其目的是赋予命名空间一个惟一的名称。
不过,很多公司常常会作为指针来使用命名空间指向实际存在的网页,这个网页包含关于命名空间的信息。
上面的 xml 文件等价于:
1
2
3
4
5
6
7
8
9
10
11
12
13
14<root xmlns:h="http://www.w3.org/TR/html4/"
xmlns:f="http://www.w3cschool.cc/furniture">
<http://www.w3.org/TR/html4/:table>
<http://www.w3.org/TR/html4/:tr>
<http://www.w3.org/TR/html4/:td>Apples</h:td>
<http://www.w3.org/TR/html4/:td>Bananas</h:td>
</http://www.w3.org/TR/html4/:tr>
</http://www.w3.org/TR/html4/:table>
<http://www.w3cschool.cc/furniture:table>
<http://www.w3cschool.cc/furniture:name>African Coffee Table</f:name>
<http://www.w3cschool.cc/furniture:width>80</f:width>
<http://www.w3cschool.cc/furniture:length>120</f:length>
</http://www.w3cschool.cc/furniture:table>
</root>可以这样理解:
xmlns:h="http://www.w3.org/TR/html4/"
定义了命名空间h
,该命名空间h
的值为http://www.w3.org/TR/html4/
。在后面的标签元素中使用到
h
时,都等价于把h
替换为http://www.w3.org/TR/html4/
,例如1
<h:table>
就等价于
1
<http://www.w3.org/TR/html4/:table>
3.XML解析技术介绍
不管是 html 文件还是 xml 文件,它们都是标记型文档,都可以使用 w3c 组织制定的
DOM
技术来解析。早期 JDK 为我们提供了两种 xml 解析技术
DOM
和SAX
(已经过时)。DOM
解析技术是 W3C 组织制定的,而所有的编程语言都对这个解析技术使用了自己语言的特点进行实现。Java 对DOM
技术解析标记也做了实现。- sun 公司在 JDK5 版本对
DOM
解析技术进行升级:SAX
(Simple API for XML)SAX
解析,它跟 W3C 制定的解析不太一样。它是以类似事件机制通过回调告诉用户当前正在解析的内容。它是一行一行的读取 xml 文件进行解析的。不会创建大量的dom
对象。所以它在解析 xml 的时候,在内存的使用上和性能上,都优于DOM
解析。
第三方解析:
jdom
在dom
的基础上进行了封装。dom4j
又对jdom
进行了封装。
4.★★★dom4j解析技术
由于
dom4j
它不是 sun 公司的技术,而属于第三方公司的技术,我们需要使用dom4j
就需要到dom4j
官网 dom4j 下载dom4j
的jar
包。dom4j
编程步骤:- 先加载 xml 文件创建 Document 对象。
- 通过 Document 对象拿到根元素对象。
- 通过
根元素.elelemts(标签名);
可以返回一个集合,这个集合里放着所有你指定的标签名的元素对象。 - 找到你想要修改、删除的子元素,进行相应的操作。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42package com.f.dom4j;
import org.dom4j.Document;
import org.dom4j.Element;
import org.junit.jupiter.api.Test;
import org.dom4j.io.SAXReader;
import java.util.List;
/**
* @author fzy
* @date 2023/10/17 19:23
*/
public class Dom4jTest {
public void test() throws Exception {
//1.创建一个SaxReader输入流,去读取xml配置文件,生成Document对象
SAXReader saxReader = new SAXReader();
Document document = saxReader.read(System.getProperty("user.dir") +
"\\src\\main\\resources\\books.xml");
//2.通过Document对象获取根元素
Element rootElement = document.getRootElement();
//3.通过根元素获取标签对象
List<Element> books = rootElement.elements("book");
//4.遍历,处理每个标签对象
for (Element book : books) {
//4.1得到book标签对象的属性值
String snValue = book.attributeValue("sn");
//4.2得到book标签对象中的name标签对象
Element nameElement = book.element("name");
String name = nameElement.getText(); //得到标签对象的内容
//或者直接得到指定标签对象的内容
String author = book.elementText("author");
String price = book.elementText("price");
//4.3根据得到的 sn、name、author、price创建Book对象
System.out.println(new Book(snValue, name, author, Double.parseDouble(price)));
}
}
}