From:http://201109025948.iteye.com/blog/1182898
XML在不同的语言里解析方式都是一样的,只不过实现的语法不同,基本的解析方式包括SAX和DOM。
#SAX是基于事件流的解析,DOM是基于XML文档树结构的解析。
#DOM解析(W3C的DOM--org.w3c.dom):
DOM是用与平台和语言无关的方式表示XML文档的官方W3C标准。
解析器读取整个文档,然后构建一个驻留内存的树结构,然后代码就可以使用DOM接口来操作这个树结构。
优点:整个文档树存在内存中,便于操作;支持删除、修改、重新排列等。
缺点:将整个文档调入内存(包括无用的节点),浪费空间和时间。
使用场合:一旦解析了文档还需要多次访问这些数据;硬件资源充足(如内存,cpu)
代码:
import java.io.*;
import java.util.*;
import org.w3c.dom.*;
import javax.xml.parsers.*;
DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance();
DocumentBuilder builder=factory.newDocumentBuilder();
Document doc = builder.parse(f);
#SAX解析: 解析器发现元素开始、元素结束、文本、文档的开始或结束时,发送事件,程序员编写响应这些时间的代码,保存数据。
优点:不用事先调入整个文档,占用资源少;
SAX解析器代码比DOM解析器小,适用于applet、下载;
缺点:不是持久的;事件过后,若 没保存数据,那么数据就丢了;
无状态性;
从事件中只能得到文档,但不知道该文本属于哪个元素;
使用场合:Applet;
只需要XML文档的少量内容,很少回头访问,机器内存少。
SAX 解析器的时候编码工作会比较困难,而且很难同时访问同一个文档中的多处不同数据。
代码:
import org.xml.sax.*;
import org.xml.sax.helpers.*;
import javax.xml.parsers.*;
SAXParserFactory sf = SAXParserFactory.newInstance();
SAXParser sp = sf.newSAXParser();
MyXMLReader reader = new MyXMLReader();
sp.parse(new InputSource("data_10k.xml"),reader);
#DOM4J解析: DOM4J是一个非常优秀的JAVA XML API,具有性能优异、功能强大和极端易用使用的特点。
代码:
import java.io.*;
import java.util.*;
import org.dom4j.*;
import org.dom4j.io.*;
File f = new File("data_10k.xml");
SAXReader reader = new SAXReader();
Document doc = reader.read(f);
#JDOM解析: JDOM的目的是成为java特定文档模型,简化与XML的交互并且比使用DOM实现更快。
为减少DOM SAX的编码量,出现了JDOM;
优点:20-80原则,极大的减少了代码量。
使用场合:要实现的功能简单、如解析、创建等,但在底层,JDOM还是使用SAX、DOM等。
JDOM与DOM主要有两个方面不同:
JDOM使用具体类而不使用接口。这在某些方面简化了API,但是也限制了灵活性。
API大量是用了Collections类,简化了那些已经熟悉这些类得JAVA开发者的使用。
JDOM自身不包含解析器,通常是用SAX2解析器来解析和验证输入XML文档。
代码:
import java.io.*;
import java.util.*;
import org.jdom.*;
import org.jdom.input.*;
SAXBuilder builder = new SAXBuilder();
Document doc = builder.build(new File("data_10k.xml"));
开发人员之所以往往不愿意使用SAX,原因是它很复杂,不过又只好使用它,因为没有其他切实可行的选择。不然,如果XML文件超过几百KB,DOM的内存开销和性能下降对应用开发人员来说就会成为棘手的绊脚石,这样就无法满足项目对性能的最低要求。
#XPP3解析: 这是一种比较古老的XML解析方式,其官方网站上也曾经说明这种解析方式在性能上是比较可靠的。
先贴出这种解析方式的完整解析代码:
public static void xpp3Parse(){
XmlPullParserFactory factory;
try {
factory = XmlPullParserFactory.newInstance();
factory.setNamespaceAware(true);
XmlPullParser xpp = factory.newPullParser();
long start = System.currentTimeMillis();
xpp.setInput(new FileInputStream("d:\\inBox.xml"),"utf-8");
int eventType = xpp.getEventType();
while (true) {
switch (eventType) {
case XmlPullParser.START_DOCUMENT:
System.out.println("Start of Document");
break;
case XmlPullParser.START_TAG:
System.out.println("Start of Tag: " + xpp.getName());
if(xpp.getAttributeCount() > 0){
for(int i=0;i<xpp.getAttributeCount();i++){
System.out.println(xpp.getAttributeName(i) + " = " + xpp.getAttributeValue(i));
}
}
break;
case XmlPullParser.END_TAG:
System.out.println("END_TAG: " + xpp.getName());
break;
case XmlPullParser.TEXT:
System.out.println("Text: " + xpp.getText());
break;
}
if (eventType == XmlPullParser.END_DOCUMENT)
break;
eventType = xpp.next();
}
System.out.println("XPP3耗时:"+(System.currentTimeMillis() - start)+" ms");
} catch (XmlPullParserException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}