一 简介
在Java中,可以使用多种方式来解析XML文件,其中最常见的可能就是DOM、SAX、JDOM、DOM4J这四种方式了。其中,DOM和SAX这两种解析XML文件的方式有jdk自带的API,因此不需要额外引入第三方的jar包。与之相反的是,JDOM和DOM4J这两种解析方式都是第三方开源项目,因此在使用这两种方式解析XML文件时需要额外引入相关jar包
(1)DOM
DOM是用与平台和语言无关的方式表示XML文档的官方W3C标准。DOM是以层次结构组织的节点或信息片断的集合,这个层次结构允许开发人员在树中寻找特定信息。分析该结构通常需要加载整个文档和构造层次结构,然后才能做任何工作
因此在使用DOM这种方式来解析XML文件时,解析器需要将整个XML文件读到内存中,形成一个树形结构方便后面的操作
-
优点: 整个文档树在内存中,便于操作;支持删除、修改、重新排列等多种操作
-
缺点: 将整个文档调入内存(包括无用的节点),浪费时间和内存,如果XML过大容易出现内存溢出问题
(2)SAX
由于DOM解析XML文件时需要一次性读入整个文件,当文件过大时有诸多不足之处,因此为了解决这个问题,出现了SAX这种基于事件驱动的解析方式
SAX解析XML文件通过从上往下依次不断载入内容到内存中,当解析器发现元素的开始标志、结束标志、文本、文档的开始标志、文档的结束标志等相关标志时,将会触发一些对应的事件,我们需要做的就是在这些事件的方法中编写自定义代码,用于保存获取到的数据
-
优点:不用事先载入整个文档,占用资源(内存)少;使用SAX方式解析编写的代码要比使用DOM解析编写的代码少
-
缺点:不是持久的;事件过后,若没保存数据,那么数据就丢了;无状态性;从事件中只能得到文本,但不知该文本属于哪个元素
(3)JDOM
使用JDOM来解析XML文件跟使用DOM来解析从代码上来说解析思路是差不多的。JDOM与DOM主要有两方面不同:首先,JDOM仅使用具体类而不使用接口,这在某些方面简化了API,但是也限制了灵活性。其次是JDOM的API大量使用了Collections类,简化了那些已经熟悉这些类的Java开发者的使用
-
优点:开源项目;比DOM容易理解
-
缺点:JDOM自身不包含解析器。它通常使用SAX2解析器来解析和验证输入XML文档
(4)DOM4J
DOM4J 是一个非常非常优秀的Java XML API,具有性能优异、功能强大和极端易用使用的特点,同时它也是一个开放源代码的软件。如今你可以看到越来越多的 Java 软件都在使用 DOM4J 来读写 XML
由于DOM4J无论在性能方面还是代码编写方面都是很强大的,特别是当XML文件很大时使用DOM4J来解析也会有较高的效率。因此,建议平时需要解析XML文件可以考虑尽可能使用DOM4J来解析。当然如果文件非常小的话使用DOM来解析也是可以的
优点:
-
开源项目
-
DOM4J是JDOM的一种智能分支,它合并了需要超出基本XML文档的功能
-
具有性能优异、灵活性好、简单易用等特点
二 DOM解析XML文件
(1)在进行代码编写测试之前,需要准备一个XML文件,我这里准备的文件是:demo1.xml
demo1.xml:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
<?
xml
version
=
"1.0"
encoding
=
"UTF-8"
?>
<
employees
>
<
user
id
=
"1"
>
<
name
>zifangsky</
name
>
<
age
>10</
age
>
<
sex
>male</
sex
>
<
contact
>https://www.zifangsky.cn</
contact
>
</
user
>
<
user
id
=
"2"
>
<
name
>admin</
name
>
<
age
>20</
age
>
<
sex
>male</
sex
>
<
contact
>https://www.tar.pub</
contact
>
</
user
>
</
employees
>
|
(2)代码实例:
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
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
|
package
cn.zifangsky.xml;
import
javax.xml.parsers.DocumentBuilder;
import
javax.xml.parsers.DocumentBuilderFactory;
import
org.w3c.dom.Document;
import
org.w3c.dom.Element;
import
org.w3c.dom.NamedNodeMap;
import
org.w3c.dom.Node;
import
org.w3c.dom.NodeList;
public
class
DomParseTest {
public
static
void
main(String[] args) {
DocumentBuilderFactory dFactory = DocumentBuilderFactory.newInstance();
try
{
DocumentBuilder dBuilder = dFactory.newDocumentBuilder();
// 加载一个xml文件
Document document = dBuilder
.parse(
"src/cn/zifangsky/xml/demo1.xml"
);
// 获取user节点集合
NodeList userList = document.getElementsByTagName(
"user"
);
int
userListLength = userList.getLength();
System.out.println(
"此xml文件一共有"
+ userListLength +
"个'user'节点\n"
);
// 遍历
for
(
int
i =
0
; i < userListLength; i++) {
// 通过item方法获取指定的节点
Node userNode = userList.item(i);
// *********************解析属性***********************
// 获取该节点的所有属性值,如:id="1"
NamedNodeMap userAttributes = userNode.getAttributes();
System.out.println(
"'user'节点"
+ i +
"有"
+ userAttributes.getLength() +
"个属性:"
);
/**
* 1 在不清楚有哪些属性的情况下可以遍历所有属性,
* 并获取每个属性对应的属性名和属性值
* */
for
(
int
j =
0
; j < userAttributes.getLength(); j++) {
// 'user'节点的每个属性组成的节点
Node attrnNode = userAttributes.item(j);
System.out.println(
"属性"
+ j +
": 属性名: "
+ attrnNode.getNodeName() +
" ,属性值: "
+ attrnNode.getNodeValue());
}
/**
* 2 在知道有哪些属性值的情况下,可以获取指定属性名的属性值
* */
Element userElement = (Element) userList.item(i);
System.out.println(
"属性为'id'的对应值是: "
+ userElement.getAttribute(
"id"
));
// *********************解析子节点************************
NodeList childNodes = userNode.getChildNodes();
System.out.println(
"\n该节点一共有"
+ childNodes.getLength()
+
"个子节点,分别是:"
);
// 遍历子节点
for
(
int
k =
0
; k < childNodes.getLength(); k++) {
Node childNode = childNodes.item(k);
// 从输出结果可以看出,每行后面的换行符也被当做了一个节点,因此是:4+5=9个子节点
// System.out.println("节点名: " + childNode.getNodeName() +
// ",节点值: " + childNode.getTextContent());
// 仅取出子节点中的'ELEMENT_NODE',换行符组成的Node是'TEXT_NODE'
if
(childNode.getNodeType() == Node.ELEMENT_NODE) {
// System.out.println("节点名: " + childNode.getNodeName()
// + ",节点值: " + childNode.getTextContent());
// 最低一层是文本节点,节点名是'#text'
System.out.println(
"节点名: "
+ childNode.getNodeName()
+
",节点值: "
+ childNode.getFirstChild().getNodeValue());
}
}
System.out.println(
"***************************"
);
}
}
catch
(Exception e) {
e.printStackTrace();
}
}
}
|
从上面的代码可以看出,在使用DOM来解析XML文件时一般需要做以下几步操作:
-
创建一个文档构建器工厂(DocumentBuilderFactory)实例
-
通过上面的DocumentBuilderFactory生成一个新的文档构建器(DocumentBuilder)
-
使用上面的DocumentBuilder解析(parse)一个XML文件,生成文档树(Document)
-
通过Document获取指定id的节点或根据节点名获取所有符合条件的节点集合
-
遍历每个节点,可以获取该节点的属性、属性值等相关参数
-
如果该节点还存在子节点,可以根据上面的方式继续遍历它的所有子节点
(3)上面的代码输出如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
此xml文件一共有2个'user'节点
'user'节点0有1个属性:
属性0: 属性名: id ,属性值: 1
属性为'id'的对应值是: 1
该节点一共有9个子节点,分别是:
节点名: name,节点值: zifangsky
节点名: age,节点值: 10
节点名: sex,节点值: male
节点名: contact,节点值: https://www.zifangsky.cn
***************************
'user'节点1有1个属性:
属性0: 属性名: id ,属性值: 2
属性为'id'的对应值是: 2
该节点一共有9个子节点,分别是:
节点名: name,节点值: admin
节点名: age,节点值: 20
节点名: sex,节点值: male
节点名: contact,节点值: https://www.tar.pub
***************************
|
三 SAX解析XML文件
在进行本次测试时,并不引入其他XML文件,仍然使用上面的demo1.xml文件
由于SAX解析XML文件跟DOM不同,它并不是将整个文档都载入到内存中。解析器在解析XML文件时,通过逐步载入文档,从上往下一行行的解析XML文件,在碰到文档开始标志、节点开始标志、文本文档、节点结束标志、文档结束标志时进行对应的事件处理。因此,我们首先需要构造一个这样的解析处理器来申明:当解析到这些标志时,我们需要进行怎样的自定义处理
(1)解析处理器SAXParseHandler.java:
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
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
|
package
cn.zifangsky.xml;
import
org.xml.sax.Attributes;
import
org.xml.sax.SAXException;
import
org.xml.sax.helpers.DefaultHandler;
public
class
SAXParseHandler
extends
DefaultHandler {
/**
* 用来遍历XML文件的开始标签
* */
@Override
public
void
startElement(String uri, String localName, String qName,
Attributes attributes)
throws
SAXException {
super
.startElement(uri, localName, qName, attributes);
//解析'user'元素的属性值
// if(qName.equals("user"))
// System.out.println("'user'元素的id属性值是:" + attributes.getValue("id"));
//遍历并打印元素的属性
int
length = attributes.getLength();
if
(length >
0
){
System.out.println(
"元素'"
+ qName +
"'的属性是:"
);
for
(
int
i=
0
;i<length;i++){
System.out.println(
" 属性名:"
+ attributes.getQName(i) +
",属性值: "
+ attributes.getValue(i));
}
System.out.println();
}
System.out.print(
"<"
+ qName +
">"
);
}
/**
* 用来遍历XML文件的结束标签
* */
@Override
public
void
endElement(String uri, String localName, String qName)
throws
SAXException {
super
.endElement(uri, localName, qName);
System.out.println(
"<"
+ qName +
"/>"
);
}
/**
* 文本内容
* */
public
void
characters(
char
[] ch,
int
start,
int
length)
throws
SAXException {
super
.characters(ch, start, length);
String value =
new
String(ch, start, length).trim();
if
(!value.equals(
""
))
System.out.print(value);
}
/**
* 用来标识解析开始
* */
@Override
public
void
startDocument()
throws
SAXException {
System.out.println(
"SAX解析开始"
);
super
.startDocument();
}
/**
* 用来标识解析结束
* */
@Override
public
void
endDocument()
throws
SAXException {
System.out.println(
"SAX解析结束"
);
super
.endDocument();
}
}
|
关于上面代码的一些含义我这里就不再做解释了,可以自行参考注释内容
(2)测试:
SAXParseTest.java文件:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
package
cn.zifangsky.xml;
import
javax.xml.parsers.SAXParser;
import
javax.xml.parsers.SAXParserFactory;
public
class
SAXParseTest {
public
static
void
main(String[] args) {
SAXParserFactory sFactory = SAXParserFactory.newInstance();
try
{
SAXParser saxParser = sFactory.newSAXParser();
//创建自定义的SAXParseHandler解析类
SAXParseHandler saxParseHandler =
new
SAXParseHandler();
saxParser.parse(
"src/cn/zifangsky/xml/demo1.xml"
, saxParseHandler);
}
catch
(Exception e) {
e.printStackTrace();
}
}
}
|
从上面的代码可以看出,使用SAX解析XML文件时,一共传递进去了两个参数,分别是:XML文件路径和前面定义的解析处理器。有了具体的XML文件以及对应的处理器来处理对应的标志事情,因此SAX这种解析方式就可以顺利地进行解析工作了
(3)上面测试的输出如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
SAX解析开始
<employees>元素'user'的属性是:
属性名:id,属性值: 1
<user><name>zifangsky<name/>
<age>10<age/>
<sex>male<sex/>
<contact>https://www.zifangsky.cn<contact/>
<user/>
元素'user'的属性是:
属性名:id,属性值: 2
<user><name>admin<name/>
<age>20<age/>
<sex>male<sex/>
<contact>https://www.tar.pub<contact/>
<user/>
<employees/>
SAX解析结束
|
四 JDOM解析XML文件
跟前面两种解析方式不同的是,使用JDOM来解析XML文件需要下载额外的jar包
(1)下载jar包并导入到项目中:
下载地址:http://www.jdom.org/downloads/index.html
目前最新版本是:JDOM 2.0.6
然后将下载得到的“jdom-2.0.6.jar”文件导入到测试项目中
注:关于如何在一个Java项目中导入额外的jar,这里将不多做解释,不太会的童鞋可以自行百度
(2)测试代码:
JDOMTest.java:
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
|
package
cn.zifangsky.xml;
import
java.util.List;
import
org.jdom2.Document;
import
org.jdom2.Element;
import
org.jdom2.input.SAXBuilder;
public
class
JDOMTest {
/**
* @param args
*/
public
static
void
main(String[] args) {
SAXBuilder saxBuilder =
new
SAXBuilder();
try
{
Document document = saxBuilder.build(
"src/cn/zifangsky/xml/demo1.xml"
);
//获取XML文件的根节点
Element rootElement = document.getRootElement();
// System.out.println(rootElement.getName());
List<Element> usersList = rootElement.getChildren();
//获取子节点
for
(Element u : usersList){
// List<Attribute> attributes = u.getAttributes();
// for(Attribute attribute : attributes){
// System.out.println("属性名:" + attribute.getName() + ",属性值:" + attribute.getValue());
// }
System.out.println(
"'id'的值是: "
+ u.getAttributeValue(
"id"
));
}
}
catch
(Exception e) {
e.printStackTrace();
}
}
}
|
从上面的代码可以看出,使用JDOM来解析XML文件,主要需要做以下几个步骤:
-
新建一个SAXBuilder
-
通过SAXBuilder的build方法传入一个XML文件的路径得到Document
-
通过Document的getRootElement方法获取根节点
-
通过getChildren方法获取根节点的所有子节点
-
然后是遍历每个子节点,获取属性、属性值、节点名、节点值等内容
-
如果该节点也有子节点,然后同样可以通过getChildren方法获取该节点的子节点
-
后面的步骤跟上面一样,不断递归到文本节点截止
(3)上面测试的输出如下:
1
2
|
'id'的值是: 1
'id'的值是: 2
|
五 DOM4J解析XML文件
jar包下载地址:https://sourceforge.net/projects/dom4j/files/
同样,在使用DOM4J解析XML文件时需要往项目中引入“dom4j-1.6.1.jar”文件
(1)一个简单实例:
i)DOM4JTest.java:
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
42
43
44
45
46
47
48
|
package
cn.zifangsky.xml;
import
java.io.File;
import
java.util.Iterator;
import
java.util.List;
import
org.dom4j.Attribute;
import
org.dom4j.Document;
import
org.dom4j.Element;
import
org.dom4j.io.SAXReader;
public
class
DOM4JTest {
public
static
void
main(String[] args) {
SAXReader reader =
new
SAXReader();
try
{
Document document = reader.read(
new
File(
"src/cn/zifangsky/xml/demo1.xml"
));
//获取XML文件的根节点
Element rootElement = document.getRootElement();
System.out.println(rootElement.getName());
//通过elementIterator方法获取迭代器
Iterator<Element> iterator = rootElement.elementIterator();
//遍历
while
(iterator.hasNext()){
Element user = iterator.next();
//获取属性并遍历
List<Attribute> aList = user.attributes();
for
(Attribute attribute : aList){
System.out.println(
"属性名:"
+ attribute.getName() +
",属性值:"
+ attribute.getValue());
}
//子节点
Iterator<Element> childList = user.elementIterator();
while
(childList.hasNext()){
Element child = childList.next();
// System.out.println(child.getName() + " : " + child.getTextTrim());
System.out.println(child.getName() +
" : "
+ child.getStringValue());
}
}
}
catch
(Exception e) {
e.printStackTrace();
}
}
}
|
从上面的代码可以看出,跟前面的JDOM解析方式流程是差不多的,并且关键地方也有注释,因此这里就不多做解释了
ii)上面的代码输出如下:
1
2
3
4
5
6
7
8
9
10
11
|
employees
属性名:id,属性值:1
name : zifangsky
age : 10
sex : male
contact : https://www.zifangsky.cn
属性名:id,属性值:2
name : admin
age : 20
sex : male
contact : https://www.tar.pub
|
(2)将XML文件解析成Java对象:
i)为了方便测试,这里准备一个新的XML文件:
demo2.xml:
1
2
3
4
5
6
7
8
9
|
<?
xml
version
=
"1.0"
encoding
=
"UTF-8"
?>
<
user
id
=
"2"
>
<
name
>zifangsky</
name
>
<
age
>100</
age
>
<
sex
>男</
sex
>
<
contact
>https://www.zifangsky.cn</
contact
>
<
ownPet
id
=
"1"
>旺财</
ownPet
>
<
ownPet
id
=
"2"
>九头猫妖</
ownPet
>
</
user
>
|
ii)同时准备一个Java实体类,恰好跟上面的XML文件中的属性相对应:
User.java:
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
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
|
package
cn.zifangsky.xml;
import
java.util.List;
public
class
User {
private
String name;
private
String sex;
private
int
age;
private
String contact;
private
List<String> ownPet;
public
String getName() {
return
name;
}
public
void
setName(String name) {
this
.name = name;
}
public
String getSex() {
return
sex;
}
public
void
setSex(String sex) {
this
.sex = sex;
}
public
int
getAge() {
return
age;
}
public
void
setAge(
int
age) {
this
.age = age;
}
public
String getContact() {
return
contact;
}
public
void
setContact(String contact) {
this
.contact = contact;
}
protected
List<String> getOwnPet() {
return
ownPet;
}
protected
void
setOwnPet(List<String> ownPet) {
this
.ownPet = ownPet;
}
@Override
public
String toString() {
return
"User [name="
+ name +
", sex="
+ sex +
", age="
+ age
+
", contact="
+ contact +
", ownPet="
+ ownPet +
"]"
;
}
}
|
iii)测试代码:
XMLtoJava.java:
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
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
|
package
cn.zifangsky.xml;
import
java.io.File;
import
java.util.ArrayList;
import
java.util.List;
import
org.dom4j.Document;
import
org.dom4j.Element;
import
org.dom4j.io.SAXReader;
public
class
XMLtoJava {
public
User parseXMLtoJava(String xmlPath){
User user =
new
User();
List<String> ownPet =
new
ArrayList<String>();
SAXReader saxReader =
new
SAXReader();
try
{
Document document = saxReader.read(
new
File(xmlPath));
Element rootElement = document.getRootElement();
//获取根节点
List<Element> children = rootElement.elements();
//获取根节点的子节点
//遍历
for
(Element child : children){
String elementName = child.getName();
//节点名
String elementValue = child.getStringValue();
//节点值
switch
(elementName) {
case
"name"
:
user.setName(elementValue);
break
;
case
"sex"
:
user.setSex(elementValue);
break
;
case
"age"
:
user.setAge(Integer.valueOf(elementValue));
break
;
case
"contact"
:
user.setContact(elementValue);
break
;
case
"ownPet"
:
ownPet.add(elementValue);
break
;
default
:
break
;
}
}
user.setOwnPet(ownPet);
}
catch
(Exception e) {
e.printStackTrace();
}
return
user;
}
public
static
void
main(String[] args) {
XMLtoJava demo =
new
XMLtoJava();
User user = demo.parseXMLtoJava(
"src/cn/zifangsky/xml/demo2.xml"
);
System.out.println(user);
}
}
|
经过前面的分析之后,上面这个代码也是很容易理解的:通过遍历节点,如果节点名跟Java类中的某个属性名相对应,那么就将节点值赋值给该属性
iv)上面的代码输出如下:
1
|
User [name=zifangsky, sex=男, age=100, contact=https://www.zifangsky.cn, ownPet=[旺财, 九头猫妖]]
|
(3)解析一个XML文件并尽可能原样输出:
DOM4JTest2:
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
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
|
package
cn.zifangsky.xml;
import
java.io.File;
import
java.util.List;
import
org.dom4j.Attribute;
import
org.dom4j.Document;
import
org.dom4j.Element;
import
org.dom4j.io.SAXReader;
public
class
DOM4JTest2 {
/**
* 解析XML文件并尽可能原样输出
*
* @param xmlPath
* 待解析的XML文件路径
* @return null
* */
public
void
parse(String xmlPath) {
SAXReader saxReader =
new
SAXReader();
try
{
Document document = saxReader.read(
new
File(xmlPath));
Element rootElement = document.getRootElement();
print(rootElement,
0
);
}
catch
(Exception e) {
e.printStackTrace();
}
}
/**
* 打印一个XML节点的详情
*
* @param element
* 一个XML节点
* @param level
* 用于判断xml节点前缩进多少的标识,每深入一层则多输出4个空格
* @return null
* */
public
void
print(Element element,
int
level) {
List<Element> elementList = element.elements();
// 当前节点的子节点List
// 空格
StringBuffer spacebBuffer =
new
StringBuffer(
""
);
for
(
int
i =
0
; i < level; i++)
spacebBuffer.append(
" "
);
String space = spacebBuffer.toString();
// 输出开始节点及其属性值
System.out.print(space +
"<"
+ element.getName());
List<Attribute> attributes = element.attributes();
for
(Attribute attribute : attributes)
System.out.print(
" "
+ attribute.getName() +
"=\""
+ attribute.getText() +
"\""
);
// 有子节点
if
(elementList.size() >
0
) {
System.out.println(
">"
);
// 遍历并递归
for
(Element child : elementList) {
print(child, level +
1
);
}
// 输出结束节点
System.out.println(space +
"</"
+ element.getName() +
">"
);
}
else
{
// 如果节点没有文本则简化输出
if
(element.getStringValue().trim().equals(
""
))
System.out.println(
" />"
);
else
System.out.println(
">"
+ element.getStringValue() +
"</"
+ element.getName() +
">"
);
}
}
public
static
void
main(String[] args) {
DOM4JTest2 test2 =
new
DOM4JTest2();
test2.parse(
"src/cn/zifangsky/xml/demo3.xml"
);
}
}
|
这段代码同样没有什么新的东西,原理就是利用递归来不断进行解析输出,注意一下不同层次的节点的缩进即可。刚开始测试时建议用一些结构比较简单的代码,如上面的demo1.xml和demo2.xml文件。在测试没问题时可以选择一些复杂的XML文件来测试是否能够正常输出,比如:
demo3.xml:
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
|
<?
xml
version
=
"1.0"
encoding
=
"UTF-8"
?>
<
application
xmlns
=
"http://wadl.dev.java.net/2009/02"
xmlns:xs
=
"http://www.w3.org/2001/XMLSchema"
>
<
grammars
/>
<
resources
base
=
"http://localhost:9080/Demo/services/json/checkCode"
>
<
resource
path
=
"/"
>
<
resource
path
=
"addCheckCode"
>
<
method
name
=
"POST"
>
<
request
>
<
representation
mediaType
=
"application/octet-stream"
/>
</
request
>
<
response
>
<
representation
mediaType
=
"application/xml"
>
<
param
name
=
"result"
style
=
"plain"
type
=
"xs:int"
/>
</
representation
>
<
representation
mediaType
=
"application/json"
>
<
param
name
=
"result"
style
=
"plain"
type
=
"xs:int"
/>
</
representation
>
</
response
>
</
method
>
</
resource
>
<
resource
path
=
"findCheckCodeByProfileId"
>
<
method
name
=
"POST"
>
<
request
>
<
representation
mediaType
=
"application/octet-stream"
>
<
param
name
=
"request"
style
=
"plain"
type
=
"xs:long"
/>
</
representation
>
</
request
>
<
response
>
<
representation
mediaType
=
"application/xml"
/>
<
representation
mediaType
=
"application/json"
/>
</
response
>
</
method
>
</
resource
>
</
resource
>
</
resources
>
</
application
>
|
为什么我在标题上说的是尽可能原样输出,其原因就是上面那段解析代码在碰到下面这种XML节点时,输出就不一样了:
1
2
3
4
|
<dc:creator><![CDATA[admin]]></dc:creator>
<category><![CDATA[运维]]></category>
<category><![CDATA[zabbix]]></category>
<category><![CDATA[端口]]></category>
|
这段XML文档节点最后输出如下:
1
2
3
4
|
<creator>admin</creator>
<category>运维</category>
<category>zabbix</category>
<category>端口</category>
|