四种解析XML文件的方法

XML解析总结与比较

1、DOM
DOM是基于树的结构,通常需要加载整文档和构造DOM树,然后才能开始工作。
优点:
    a、由于整棵树在内存中,因此可以对xml文档随机访问
    b、可以对xml文档进行修改操作
    c、较sax,dom使用也更简单。
缺点:
    a、整个文档必须一次性解析完
    a、由于整个文档都需要载入内存,对于大文档成本高
2、SAX
SAX类似流媒体,它基于事件驱动的,因此无需将整个文档载入内存,使用者只需要监听自己感兴趣的事件即可。
优点:
    a、无需将整个xml文档载入内存,因此消耗内存少
    b、可以注册多个ContentHandler
缺点:
    a、不能随机的访问xml中的节点
    b、不能修改文档
3、JDOM
JDOM是纯Java的处理XML的API,其API中大量使用Collections类,
优点:
    a、DOM方式的优点
    b、具有SAX的Java规则
缺点
    a、DOM方式的缺点
4、DOM4J
    这4中xml解析方式中,最优秀的一个,集易用和性能于一身。
     JDOM 和 DOM 在性能测试时表现不佳,在测试 10M 文档时内存溢出。在小文档情况下还值得考虑使用 DOM 和 JDOM。虽然 JDOM 的开发者已经说明他们期望在正式发行版前专注性能问题,但是从性能观点来看,它确实没有值得推荐之处。另外,DOM 仍是一个非常好的选择。DOM 实现广泛应用于多种编程语言。它还是许多其它与 XML 相关的标准的基础,因为它正式获得 W3C 推荐(与基于非标准的 Java 模型相对),所以在某些类型的项目中可能也需要它(如在 JavaScript 中使用 DOM)。 
  SAX表现较好,这要依赖于它特定的解析方式。一个 SAX 检测即将到来的XML流,但并没有载入到内存(当然当XML流被读入时,会有部分文档暂时隐藏在内存中)。 

  无疑,DOM4J是这场测试的获胜者,目前许多开源项目中大量采用 DOM4J,例如大名鼎鼎的 Hibernate 也用 DOM4J 来读取 XML 配置文件。如果不考虑可移植性,可以采用DOM4J解析文件。


1、DOM解析

DOM 解析器把 XML 文档转化为一个包含其内容的树,并可以对树进行遍历。用 DOM 解析模型的优点是编程容易,开发人员只需要调用建树的指令,然后利用navigation APIs访问所需的树节点来完成任务。可以很容易的添加和修改树中的元素。然而由于使用 DOM 解析器的时候需要处理整个 XML 文档,所以对性能和内存的要求比较高,尤其是遇到很大的 XML 文件的时候。由于它的遍历能力,DOM 解析器常用于 XML 文档需要频繁的改变的服务中。 

import java.io.File;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;

public class MyXMLReader {
/**
* 1、新建一个解析类
* 2、以XML方式解析文件
* 返回值 void
* @Date 2017-7-23
* @param arge void
*/
public static void main(String arge[]) {
//返回以毫秒为单位的当前时间
long lasting = System.currentTimeMillis();
System.out.println("lasting="+lasting);
try {
//通过将给定路径名字符串转换为抽象路径名来创建一个新 File 实例。
File f = new File("E:/MyEclipse 代码/DataBseConnection/WebRoot/doc/1.xml");
//DocumentBuilderFactory 从 XML文档获取生成 DOM 对象树的解析器,他是一个解析器
// 获取 DocumentBuilderFactory 的新实例。
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
//从 XML 获取一个 Document,DocumentBuilder类的实例可以从 DocumentBuilderFactory.newDocumentBuilder() 方法获取
DocumentBuilder builder = factory.newDocumentBuilder();
//将给定文件的内容解析为一个 XML 文档,并且返回一个新的 DOM Document 对象。
Document doc = builder.parse(f);
//注意XML元素的大小写
NodeList nl = doc.getElementsByTagName("value");
for (int i = 0; i < nl.getLength(); i++) {
System.out.print("姓名:"+ doc.getElementsByTagName("name").item(i).getFirstChild().getNodeValue());
System.out.println(" 性别:"+ doc.getElementsByTagName("sex").item(i).getFirstChild().getNodeValue());
}
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(System.currentTimeMillis());
System.out.println("运行时间:" + (System.currentTimeMillis() - lasting)+ " 毫秒");
}
}


2、SAX解析

SAX 解析器采用了基于事件的模型,它在解析 XML 文档的时候可以触发一系列的事件,当发现给定的tag的时候,它可以激活一个回调方法,告诉该方法制定的标签已经找到。SAX 对内存的要求通常会比较低,因为它让开发人员自己来决定所要处理的tag。特别是当开发人员只需要处理文档中所包含的部分数据时,SAX 这种扩展能力得到了更好的体现。但用 SAX 解析器的时候编码工作会比较困难,而且很难同时访问同一个文档中的多处不同数据。 

import java.util.jar.Attributes;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
public class MySAXReader extends DefaultHandler {
java.util.Stack tags = new java.util.Stack();
public MySAXReader() {
super();
}
public static void main(String args[]) {
long lasting = System.currentTimeMillis();
try {
//应用程序能够配置和获取基于 SAX 的解析器以解析 XML 文档
//  获取 SAXParserFactory 的一个新实例。
SAXParserFactory sf = SAXParserFactory.newInstance();
//包装 XMLReader 实现类
SAXParser sp = sf.newSAXParser();
MySAXReader reader = new MySAXReader();
//InputSource XML 实体的单一输入源
//SAX 解析器将使用 InputSource 对象来确定如何读取 XML 输入
//parse(InputStream is, HandlerBase hb) 
             //  使用指定的 HandlerBase 将给定的 InputStream 实例的内容解析为 XML。
sp.parse(new InputSource("E:/MyEclipse  代码/DataBseConnection/WebRoot/doc/1.xml"), reader);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("运行时间:" + (System.currentTimeMillis() - lasting)
+ " 毫秒");
}
public void characters(char ch[], int start, int length)
throws SAXException {
String tag = (String) tags.peek();
if (tag.equals("name")) {
System.out.print("姓名:" + new String(ch, start, length));
}
if (tag.equals("sex")) {
System.out.println(" 性别:" + new String(ch, start, length));
}
}
public void startElement(String uri, String localName, String qName,
Attributes attrs) {
tags.push(qName);
}
}


3、JDOM解析

JDOM 与 DOM 主要有两方面不同。首先,JDOM 仅使用具体类而不使用接口。这在某些方面简化了 API,但是也限制了灵活性。第二,API 大量使用了 Collections 类,简化了那些已经熟悉这些类的 Java 开发者的使用。JDOM 文档声明其目的是“使用 20%(或更少)的精力解决 80%(或更多)Java/XML 问题”(根据学习曲线假定为 20%)。JDOM 对于大多数 Java/XML 应用程序来说当然是有用的,并且大多数开发者发现 API 比 DOM 容易理解得多。JDOM 还包括对程序行为的相当广泛检查以防止用户做任何在 XML 中无意义的事。然而,它仍需要您充分理解 XML 以便做一些超出基本的工作(或者甚至理解某些情况下的错误)。这也许是比学习 DOM 或 JDOM 接口都更有意义的工作。JDOM 自身不包含解析器。它通常使用 SAX2 解析器来解析和验证输入 XML 文档(尽管它还可以将以前构造的 DOM 表示作为输入)。它包含一些转换器以将 JDOM 表示输出成 SAX2 事件流、DOM 模型或 XML 文本文档。

import java.io.File;
import java.util.List;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.input.SAXBuilder;
public class MyJDOMReader {
public static void main(String arge[]) {
long lasting = System.currentTimeMillis();
try {
SAXBuilder builder = new SAXBuilder();
Document doc = builder.build(new File("E:/MyEclipse 代码/DataBseConnection/WebRoot/doc/1.xml"));
Element foo = doc.getRootElement();
List allChildren = foo.getChildren();
for (int i = 0; i < allChildren.size(); i++) {
System.out.print("姓名:"+ ((Element) allChildren.get(i)).getChild("name").getText());
System.out.println(" 性别:"+ ((Element) allChildren.get(i)).getChild("sex").getText());
}
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("运行时间:" + (System.currentTimeMillis() - lasting)+ " 毫秒");
}
}

4、DOM4J解析

DOM4J 的目标与 JDOM 是一样的:针对 Java 开发者的易用性和直观操作。它还致力于成为比 JDOM 更完整的解决方案,实现在本质上处理所有 Java/XML 问题的目标。在完成该目标时,它比 JDOM 更少强调防止不正确的应用程序行为,DOM4J 是一个非常非常优秀的Java XML API,具有性能优异、功能强大和极端易用使用的特点,同时它也是一个开放源代码的软件。如今你可以看到越来越多的 Java 软件都在使用 DOM4J 来读写 XML,特别值得一提的是连 Sun 的 JAXM 也在用 DOM4J。 

import java.io.*;
import java.util.*;
import org.dom4j.*;
import org.dom4j.io.*;
public class MyDOM4JReader {
public static void main(String arge[]) {
long lasting = System.currentTimeMillis();
try {
File f = new File("E:/MyEclipse  代码/DataBseConnection/WebRoot/doc/1.xml");
SAXReader reader = new SAXReader();
Document doc = reader.read(f);
Element root = doc.getRootElement();
Element foo;
for (Iterator i = root.elementIterator("value"); i.hasNext();) {
foo = (Element) i.next();
System.out.print("姓名:" + foo.elementText("name"));
System.out.println(" 性别:" + foo.elementText("sex"));
}
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("运行时间:" + (System.currentTimeMillis() - lasting)+ " 毫秒");
}
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值