`
孙玉_1987
  • 浏览: 53234 次
  • 性别: Icon_minigender_2
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

XML解析方式对比(含XPP3解析)

 
阅读更多
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();
}

}

PS:附件中的ZIP包中包含XPP3解析所需要的jar包。

简单测试:同时载入然后循环遍历80k的XML文件
XPP3:67ms
DOM4J:360ms
果然在性能上有很大的提升空间。

分享到:
评论
1 楼 zhouxingbo 2012-02-06  

相关推荐

Global site tag (gtag.js) - Google Analytics