Skip to content

Commit 8bb60cc

Browse files
author
yangjingjing
committed
init blog
1 parent beb72ed commit 8bb60cc

File tree

123 files changed

+12224
-2522
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

123 files changed

+12224
-2522
lines changed
Lines changed: 281 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,281 @@
1+
---
2+
layout: post
3+
categories: [XML]
4+
description: none
5+
keywords: XML
6+
---
7+
# JavaDOM解析XML
8+
DOM是由w3c制定的为HTML和XML文档编写的应用程序接口,全称叫做W3C DOM,它使得开发者能够修改html和xml的内容和展现方式,将网页与脚本或编程语言连接起来。
9+
10+
## DOM解析
11+
DOM全称 Document Object Model,文档对象模型。DOM 是 W3C(万维网联盟)的标准。DOM 是 W3C(万维网联盟)的标准。DOM 定义了访问 HTML 和 XML 文档的标准。
12+
13+
W3C 文档对象模型 (DOM) 是中立于平台和语言的接口,它允许程序和脚本动态地访问和更新文档的内容、结构和样式。
14+
15+
## W3C 标准
16+
HTML DOM 定义了所有 HTML 元素的对象和属性,以及访问它们的方法。 是关于如何HTML 元素的增删改查的标准。
17+
18+
XML 即可扩展标记语言(EXtensible Markup Language),类似 HTML。 XML DOM 定义了所有 XML 元素的对象和属性,以及访问它们的方法。
19+
20+
## DOM基本思想
21+
其基本思想为:
22+
- 一次性把xml文档加载进内存
23+
- 在内存中将整个XML数据转换成一个Document树形对象[Document对象]
24+
- 将XML中的标签,属性,文本都作为一个结点对象
25+
- 解析XML的时候,先将整个xml一次性读入到内存中,封装成树对象
26+
- 再对树上的结点进行操作[增删改查]
27+
28+
## 核心操作类或接口
29+
其核心操作类或接口为:
30+
31+
### Document
32+
此接口代表了整个 XML 文档,是整棵 DOM 树的根,
33+
提供了对文档中的数据进行访问和操作的入口,通过 Document 结点可以访问 XML 文件中所有的元素内容。
34+
35+
### 节点类Node
36+
此接口在整个 DOM 树种具有举足轻重的低位,DOM 操作的核心接口中有很大一部分接口是从 Node 接口继承过来的,例如:Document、Element 、Attr 、Text等接口。
37+
在 DOM树中,每一个 Node 接口代表了 DOM 树中的一个结点。
38+
### 节点列表类NodeList
39+
此接口表示的是结点的集合,一般用于列出该结点下的所有子结点。
40+
### 元素类Element
41+
是Node类最主要的子接口,在元素中可以包含属性(Attribute),故Element中有getAttribute(“Element”) 方法用来获得指定名字的属性值。
42+
43+
因为XML文件的数据类型为:标签 属性 文本
44+
故而实际应用时, 整个XML文档被当做一个 Documnet对象。标签是一个 Element对象。 属性是一个 Attr 对象。文本是一个 Text对象。
45+
46+
## java 编码实现解析xml
47+
DOM解析XML是将整个XML作为一个对象,占用内存较多。另外一个java官方的XML解析方式SAX是边扫描边解析,自顶向下依次解析,占用内存较少。
48+
49+
xml文件的内容
50+
```xml
51+
<?xml version="1.0" encoding="UTF-8"?>
52+
<root>
53+
<person id="1">
54+
<name>Tom</name>
55+
<age>20</age>
56+
</person>
57+
<person id="2">
58+
<name>Mary</name>
59+
<age>25</age>
60+
</person>
61+
</root>
62+
63+
```
64+
65+
XML与java对象之间的转换
66+
```java
67+
import javax.xml.parsers.DocumentBuilder;
68+
import javax.xml.parsers.DocumentBuilderFactory;
69+
import javax.xml.parsers.ParserConfigurationException;
70+
import javax.xml.transform.Transformer;
71+
import javax.xml.transform.TransformerException;
72+
import javax.xml.transform.TransformerFactory;
73+
import javax.xml.transform.dom.DOMSource;
74+
import javax.xml.transform.stream.StreamResult;
75+
76+
import org.w3c.dom.Document;
77+
import org.w3c.dom.Element;
78+
import org.w3c.dom.Node;
79+
import org.w3c.dom.NodeList;
80+
import java.io.File;
81+
import java.io.IOException;
82+
83+
public class Test {
84+
public static void main(String[] args) {
85+
try {
86+
// 获取 DOM 解析器工厂实例
87+
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
88+
89+
// 获取 DOM 解析器
90+
DocumentBuilder builder = factory.newDocumentBuilder();
91+
92+
// 解析XML文件
93+
Document doc = builder.parse(new File("D:\\person.xml"));
94+
95+
// 获取根节点
96+
Element root = doc.getDocumentElement();
97+
98+
// 获取 person 节点列表
99+
NodeList personList = root.getElementsByTagName("person");
100+
101+
// 遍历 person 节点列表
102+
for (int i = 0; i < personList.getLength(); i++) {
103+
Node node = personList.item(i);
104+
105+
// 判断当前 person 节点是否为 id=2 的节点
106+
if (node instanceof Element && "2".equals(((Element) node).getAttribute("id"))) {
107+
Element person = (Element) node;
108+
// 修改 age 节点的值
109+
NodeList ageList = person.getElementsByTagName("age");
110+
if (ageList.getLength() > 0) {
111+
//获取节点
112+
System.out.print(ageList.item(0).getNodeName() + ":");
113+
//获取节点值
114+
System.out.println(ageList.item(0).getFirstChild().getNodeValue());
115+
Element age = (Element) ageList.item(0);
116+
age.setTextContent("30");
117+
}
118+
}
119+
}
120+
121+
// 将修改后的文档写回到原文件
122+
TransformerFactory transformerFactory = TransformerFactory.newInstance();
123+
Transformer transformer = transformerFactory.newTransformer();
124+
DOMSource source = new DOMSource(doc);
125+
StreamResult result = new StreamResult(new File("D:\\person_new.xml"));
126+
transformer.transform(source, result);
127+
128+
System.out.println("XML文件修改成功!");
129+
} catch (ParserConfigurationException | IOException | TransformerException | org.xml.sax.SAXException e) {
130+
e.printStackTrace();
131+
}
132+
}
133+
}
134+
```
135+
136+
## java实现对XML格式的验证
137+
可以使用两种验证模式(DTD、XSD)保证XML文件格式正确,DTD和XSD均是XML约束描述语言,是XML文件的验证机制。本文以DTD为例。
138+
DTD文件格式请参考:http://www.cnblogs.com/zhengcheng/p/4278899.html
139+
看下面student.xml:
140+
```
141+
<?xml version="1.0"?>
142+
<!DOCTYPE 学生名册 SYSTEM "student.dtd">
143+
<学生名册>
144+
<学生 学号="t1">
145+
<姓名>张三</姓名>
146+
<性别>男</性别>
147+
<年龄>20</年龄>
148+
</学生>
149+
<学生 学号="t2">
150+
<姓名>李四</姓名>
151+
<性别>女</性别>
152+
<年龄>19</年龄>
153+
</学生>
154+
</学生名册>
155+
```
156+
我们看到上面这个XML指定的DTD验证文件为student.dtd:
157+
```
158+
<?xml version="1.0" encoding="UTF-8"?>
159+
160+
<!ELEMENT 学生名册 (学生*)>
161+
<!ELEMENT 学生 (姓名,性别,年龄)>
162+
<!ELEMENT 姓名 (#PCDATA)>
163+
<!ELEMENT 性别 (#PCDATA)>
164+
<!ELEMENT 年龄 (#PCDATA)>
165+
<!ATTLIST 学生 学号 ID #REQUIRED>
166+
167+
```
168+
169+
那么java DOM解析XML如何实现验证?
170+
171+
下面使用DOM解析student.xml:
172+
```
173+
public class test {
174+
175+
public static void main(String[] args) {
176+
DocumentBuilderFactory buildFactory = DocumentBuilderFactory.newInstance();
177+
//开启XML格式验证
178+
buildFactory.setValidating(true);
179+
try {
180+
DocumentBuilder build = buildFactory.newDocumentBuilder();
181+
//指定验证出错处理类MyErrorHandle
182+
build.setErrorHandler(new MyErrorHandler());
183+
//自定义解析方式,如果不设置,则使用默认实现
184+
build.setEntityResolver(new MyResolveEntity());
185+
Document doc = build.parse("student.xml");
186+
187+
getStudents(doc);
188+
} catch (ParserConfigurationException e) {
189+
e.printStackTrace();
190+
} catch (SAXException e) {
191+
e.printStackTrace();
192+
} catch (IOException e) {
193+
e.printStackTrace();
194+
}
195+
}
196+
197+
private static void getStudents(Document doc) {
198+
Element root = doc.getDocumentElement();
199+
NodeList nodeList = root.getElementsByTagName("学生");
200+
201+
for(int i=0;i<nodeList.getLength();i++){
202+
Node node = nodeList.item(i);
203+
NamedNodeMap map = node.getAttributes();
204+
System.out.println(map.item(0).getTextContent());
205+
206+
//子节点
207+
NodeList childList = node.getChildNodes();
208+
for(int j=0;j<childList.getLength();j++){
209+
Node childNode = childList.item(j);
210+
System.out.println(childNode.getTextContent());
211+
}
212+
}
213+
}
214+
}
215+
216+
public class MyErrorHandler implements ErrorHandler{
217+
218+
@Override
219+
public void warning(SAXParseException exception) throws SAXException {
220+
// TODO Auto-generated method stub
221+
222+
}
223+
224+
@Override
225+
public void error(SAXParseException exception) throws SAXException {
226+
System.out.println("发生了错误!"+exception.getMessage());
227+
228+
}
229+
230+
@Override
231+
public void fatalError(SAXParseException exception) throws SAXException {
232+
// TODO Auto-generated method stub
233+
234+
}
235+
236+
}
237+
238+
public class MyResolveEntity implements EntityResolver{
239+
240+
@Override
241+
public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException {
242+
return new InputSource("student.dtd");
243+
//return null;
244+
}
245+
246+
}
247+
```
248+
如果不设置setEntityResolver,则会使用XML中指定位置的DTD文件进行验证,
249+
```
250+
<!DOCTYPE 学生名册 SYSTEM "student.dtd">
251+
```
252+
student.dtd即指定了验证文件的位置。
253+
254+
255+
256+
257+
258+
259+
260+
261+
262+
263+
264+
265+
266+
267+
268+
269+
270+
271+
272+
273+
274+
275+
276+
277+
278+
279+
280+
281+

0 commit comments

Comments
 (0)