自大二开始学习java已有一年多了,空闲时经常会去一些java方面的网站或论坛逛逛,里面的内容着实让我这个初入java的小菜鸟大开眼界。逛网站和论坛让我收获颇多,不到一年多的时间感觉我的java水品有了明显地提高。尤其是那些辛勤劳动的博主们,是你们的无私奉献,知识共享的精神才让我们这些初学者获得了极佳的学习途径和解决困境的方法。在此向你们表示最崇高的敬意和最真挚的感谢。
学习了这么久的java,也一直想写一点东西,分享一下自己的学习经历。因为一直没有想到好写的主题,所以迟迟没有动笔。直到前几天,开始着手做一个考试系统项目时,因为需要用到xml解析器(将试题从一个xml的试题文件中解析出来),在这几天对几种常用的xml解析器进行了一次完整地学习。blogjava是一个很好的java博客网站,也是一个很好的学习交流平台,经常可以在上面看到很多优秀的文章,早就加入blogjava的冲动。今天终于在blogjava上注册一个自己的博客,从今天开始我的第一篇博客吧,我把我这几天学习xml解析器做了一个总结,作为我的第一篇博客——XML学习之旅一几种常用XML解析器的比较,与大家分享一下吧。
XML在java中的使用越来越广泛,掌握几种常用的XML解析器十分有必要。目前XML主要的解器有DOM,SAX和JDOM.
DOM是一套为合法的Well-Formed文件设计的API应用程序接口,它同时定义了这些文件的逻辑结构,访问和操作方法.由W3C制定,目标是提供一个可以通用于各种程序语言,操作系统和应用程序的API,所以DOM具有极高的兼容性.
SAX(Simple Application interface for XML)是一个为基于事件XML解析器定义的,可以免费获得的,与平台语言无关的API,它允许程序和脚本动态的访问和更新文档的内容,结构和风格.
JDOM是两位著名的 Java 开发人员兼作者,Brett Mclaughlin 和 Jason Hunter 的创作成果,它是一个开源项目,它基于树型结构,利用纯Java的技术对XML文件实现解析,生成,序列化以及其他许多操作.JDOM直接为Java编程服务,它利用强有力的Java语言的诸多特性,把SAX和DOM的功能有效地结合起来,在使用设计上尽可能地隐藏原来使用过程中的复杂性.
对于DOM和SAX在API中能直接找到,其中包含了三个软件包:
·org.w3c.dom ,W3C 推荐的用于 XML 标准规划文档对象模型的 Java 工具
·org.xml.sax ,用于对 XML 进行语法分析的事件驱动的简单 API
·javax.xml.parsers ,工厂化工具,允许应用程序开发人员获得并配置特殊的语法分析器工具 JDOM 能够替换
JDOM是一个开源项目,使用时需要导入jdom.jar到库中。相对于直接使用API中的解析器,JDOM使用起来要更简单得多。JDOM 在2000年的春天被Brett McLaughlin和Jason Hunter开发出来,以弥补DOM及SAX在实际应用当中的不足之处。下面我们通过一个实际的例子,分别使用两种方式实现解析xml的试题文件来比较两者的不同。
本次需要解析的XML文件Item.xml
<?xml version="1.0" encoding="UTF-8"?>
<list>
<item id="1">
<answer>C</answer>
<level>1</level>
<question>在下列存储器中,访问速度最快的是:_______
A) 硬盘存储器
B) 软盘存储器
C) 半导体RAM(内存储器)
D) 磁带存储器</question>
<questionType>基础题</questionType>
</item>
<item id="2">
<answer>D</answer>
<level>1</level>
<question>下面是关于微型计算机操作的四条叙述,其中正确的一条是:_______
A)系统不会用输入日期做任何事,可以随便输入过去一个日期作当天日期
B) 用户每键入一个字符时,DOS就立即将其读取并识别之
C) 启动DOS系统时,如不想输入新时间,用户只按下任意键就行
D)软盘可以在切断电源之前取出来,也可以在切断电源之后取出来</question>
<questionType>基础题</questionType>
</item>
</list>
同过使用DOM和SAX对Item.xml进行解析DomExample.java
1
package action;
2
3
/** *//**
4
*
5
* @author weiqishaonian
6
*/
7
import java.io.FileInputStream;
8
import java.io.IOException;
9
import java.io.InputStream;
10
11
import java.util.logging.Level;
12
import java.util.logging.Logger;
13
14
import javax.xml.parsers.DocumentBuilder;
15
import javax.xml.parsers.DocumentBuilderFactory;
16
import javax.xml.parsers.ParserConfigurationException;
17
//下面主要是org.xml.sax包的类
18
import org.w3c.dom.Document;
19
import org.w3c.dom.Element;
20
import org.w3c.dom.Node;
21
import org.w3c.dom.NodeList;
22
import org.xml.sax.SAXException;
23
24
public class DomExample
{
25
26
private Document doc;
27
private InputStream is = null;
28
29
public DomExample(String xmlFilePath)
{
30
try
{
31
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();//(1)得到DOM解析器的工厂实例
32
DocumentBuilder db = dbf.newDocumentBuilder();//(2)从DOM工厂获得DOM解析器
33
is = new FileInputStream(xmlFilePath);//(3)把要解析的XML文档转化为输入流,以便DOM解析器解析它
34
doc = db.parse(is);//(4)解析XML文档的输入流,得到一个Document
35
Element emt = doc.getDocumentElement();//(5)得到XML文档的根节点
36
NodeList list = emt.getChildNodes();//(6)得到节点的子节点
37
if (list != null)
{
38
for (int i = 0; i < list.getLength(); i++)
{
39
Node item = list.item(i);
40
if (item.getNodeType() == Node.ELEMENT_NODE)
{
41
//(7)取得节点的属性值
42
String id = item.getAttributes().getNamedItem("id").getNodeValue();
43
System.out.println(id);
44
//(8)轮循子节点
45
for (Node node = item.getFirstChild(); node != null; node = node.getNextSibling())
{
46
if (node.getNodeType() == Node.ELEMENT_NODE)
{
47
if (node.getNodeName().equals("answer"))
{
48
String answer = node.getFirstChild().getNodeValue();//得到试题答案
49
System.out.println(answer);
50
}
51
if (node.getNodeName().equals("level"))
{
52
String level = node.getFirstChild().getNodeValue();//得到试题等级
53
System.out.println(level);
54
}
55
if (node.getNodeName().equals("question"))
{
56
String question = node.getFirstChild().getNodeValue();//得到试题
57
System.out.println(question);
58
}
59
if (node.getNodeName().equals("questionType"))
{
60
String questionType = node.getFirstChild().getNodeValue();//得到试题类型
61
System.out.println(questionType);
62
}
63
}
64
}
65
}
66
}
67
}
68
is.close();
69
} catch (SAXException ex)
{
70
Logger.getLogger(ItemXMLParser.class.getName()).log(Level.SEVERE, null, ex);
71
} catch (IOException ex)
{
72
Logger.getLogger(ItemXMLParser.class.getName()).log(Level.SEVERE, null, ex);
73
} catch (ParserConfigurationException ex)
{
74
Logger.getLogger(ItemXMLParser.class.getName()).log(Level.SEVERE, null, ex);
75
}
76
}
77
78
public static void main(String[] args)
{
79
System.out.println("===========================================");
80
new DomExample("D:/item.xml");
81
System.out.println("===========================================");
82
}
83
84
}
85
运行结果:
run-single:
===========================================
1
C
1
在下列存储器中,访问速度最快的是:_______
A) 硬盘存储器
B) 软盘存储器
C) 半导体RAM(内存储器)
D) 磁带存储器
基础题
2
D
1
下面是关于微型计算机操作的四条叙述,其中正确的一条是:_______
A)系统不会用输入日期做任何事,可以随便输入过去一个日期作当天日期
B) 用户每键入一个字符时,DOS就立即将其读取并识别之
C) 启动DOS系统时,如不想输入新时间,用户只按下任意键就行
D)软盘可以在切断电源之前取出来,也可以在切断电源之后取出来
基础题
===========================================
BUILD SUCCESSFUL (total time: 0 seconds)
同过使用JDOM对Item.xml进行解析JDomExample.java
1
package action;
2
3
/** *//**
4
*
5
* @author weiqishaonian
6
*/
7
import java.io.FileInputStream;
8
import java.io.IOException;
9
import java.util.List;
10
import java.util.logging.Level;
11
import java.util.logging.Logger;
12
13
import org.jdom.Document;
14
import org.jdom.Element;
15
import org.jdom.JDOMException;
16
import org.jdom.input.SAXBuilder;
17
18
public class JDomExample
{
19
20
public JDomExample(String xmlFilePath)
{
21
try
{
22
SAXBuilder sb = new SAXBuilder();//
23
Document doc = sb.build(new FileInputStream(xmlFilePath));
24
Element root = doc.getRootElement(); //得到根元素
25
List items = root.getChildren(); //得到根元素所有子元素的集合
26
for (int i = 0; i < items.size(); i++)
{
27
Element item = (Element) items.get(i); //得到第i个item元素
28
System.out.println(item.getAttribute("id").toString());
29
Element answer = item.getChild("answer"); //得到试题答案
30
System.out.println(answer.getText());
31
Element level = item.getChild("level"); //得到试题等级
32
System.out.println(level.getText());
33
Element question = item.getChild("question"); //得到试题
34
System.out.println(question.getText());
35
Element questionType = item.getChild("questionType"); //得到试题类型
36
System.out.println(questionType.getText());
37
}
38
} catch (JDOMException ex)
{
39
Logger.getLogger(JDomExample.class.getName()).log(Level.SEVERE, null, ex);
40
} catch (IOException ex)
{
41
Logger.getLogger(JDomExample.class.getName()).log(Level.SEVERE, null, ex);
42
}
43
}
44
45
public static void main(String[] args)
{
46
System.out.println("===========================================");
47
new JDomExample("D:/item.xml");
48
System.out.println("===========================================");
49
}
50
}
51
52
运行结果:
run-single:
===========================================
[Attribute: id="1"]
C
1
在下列存储器中,访问速度最快的是:_______
A) 硬盘存储器
B) 软盘存储器
C) 半导体RAM(内存储器)
D) 磁带存储器
基础题
[Attribute: id="2"]
D
1
下面是关于微型计算机操作的四条叙述,其中正确的一条是:_______
A)系统不会用输入日期做任何事,可以随便输入过去一个日期作当天日期
B) 用户每键入一个字符时,DOS就立即将其读取并识别之
C) 启动DOS系统时,如不想输入新时间,用户只按下任意键就行
D)软盘可以在切断电源之前取出来,也可以在切断电源之后取出来
基础题
===========================================
BUILD SUCCESSFUL (total time: 0 seconds)
通过上面两个文件比较,我们可以明显的看出区别。JDOM解析要比使用DOM和SAX进行解析使用起来更简单,完成同样的功能用JDOM比使用DOM和SAX要少很多代码(请看DomExample.java和JDomExample.java文件),而且使用JDOM的代码看起来更为清晰。JDOM 直接为JAVA编程服务。它利用更为强有力的JAVA语言的诸多特性(方法重载、集合概念以及映射),把SAX和DOM的功能有效地结合起来。 Jdom是用Java语言读、写、操作XML的新API函数。Jason Hunter 和 Brett McLaughlin公开发布了它的1.0版本。在直觉、简单和高效的前提下,这些API函数被最大限度的优化。在接下来的篇幅里将介绍怎么用Jdom去读写一个已经存在的XML文档。在使用设计上尽可能地隐藏原来使用XML过程中的复杂性。利用JDOM处理XML文档将是一件轻松、简单的事。