为什么说 SAX 比 DOM4J 使用dom4j解析xml xml 性能低

为什么说 SAX 比 DOM4J 解析 xml 性能低?
目前公认的XML解析器性能最好的是 DOM4J
我的疑问:
DOM4J 是基于DOM文档树结构来进行解析的,来解析xml文件之前,会将整个 XML文档装载入内存形成完整的 DOM数结构,然后进行 DOM 节点的读取。
而 SAX 处理的优点非常类似于流媒体的优点,分析能够立即开始,而不是等待所有的数据被处理。而且,由于应用程序只是在读取数据时检查数据,因此不需要将数据存储在内存中;这对于大型文档来说是个巨大的优点;事实上,应用程序甚至不必解析整个文档;它可以在某个条件得到满足时停止解析;一般来说,SAX还比它的替代者DOM快许多。
但是网上有很多的 DOM, DOM4J, JDOM, SAX 对比,得出的性能结论是:
& & & & & & & & & & DOM4J & SAX & DOM & JDOM
我就感到很奇怪,SAX 的性能怎么就比 DOM4J 低了呢? 流的处理方式应该是最快的啊?
看了下官网,Dom4j好像支持SAX解析。。。
你是不是只看了中文资料啊
为什么我看到的都是说StAX快
--- 共有 2 条评论 ---
like this one?
/questions/2520950/difference-in-performance-between-stax-and-dom-parsing
我看了网上很多的对比,基本上都是这么说的
几年前我测试过,的确是这样的,df实在需要才加载,所以最快,不关xpath的事,sax读快,dom全部读进内存所以写快读慢。但这都不是重点,dom4鸡主要是文档诱人,直接扒代码,猪都会
你有自己测试过并贴下测试数据么?
SAX執行速度快
DOM編碼速度快 =_='''
因为dom4f支持xpath
--- 共有 1 条评论 ---
支持xpath应该不是原因吧,正是支持xpath,DOM4J必须加载整个XML文档啊
我个人认为 SAX 的性能应该比 DOM4J 快。DOM、SAX、JDOM和DOM4J四种方式生成XML文件性能对比
DOM、SAX、JDOM和DOM4J四种方式生成XML文件性能对比
1、定义Book类
package com.imooc.
* 存储从XML文档读取到的某个book元素的内容
* @author Administrator
public class Book {
// 书的作者
// 书的出版年份
// 书的售价
// 书的语言
// 无参构造方法
public Book() {
// 有参构造方法
public Book(int id, String name, String author, int year, double price, String language) {
this.name =
this.author =
this.year =
this.price =
this.language =
// 覆写toString()方法,显示书的属性信息
public String toString() {
return "Book [id=" + id + ", name=" + name + ", author=" + author + ", year=" + year + ", price=" + price
+ ", language=" + language + "]";
public int getId() {
public void setId(int id) {
public String getName() {
public void setName(String name) {
this.name =
public String getAuthor() {
public void setAuthor(String author) {
this.author =
public int getYear() {
public void setYear(int year) {
this.year =
public double getPrice() {
public void setPrice(double price) {
this.price =
public String getLanguage() {
public void setLanguage(String language) {
this.language =
2、使用SAX方式解析XML文档,并存储在ArrayList对象中
2.1、定义Handler类
package com.imooc.
import java.util.ArrayL
import org.xml.sax.A
import org.xml.sax.SAXE
import org.xml.sax.helpers.DefaultH
import com.imooc.book.B
* Handler类继承DefaultHandler类,并覆写startElement、endElement和characters方法
* @author Administrator
public class Handler extends DefaultHandler {
// 存储读到的书籍
private ArrayList&Book& books = new ArrayList&Book&();
// 元素内容
String textContent =
// 声明一个Book对象
Book book =
// 获得书籍
public ArrayList&Book& getBooks() {
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
super.startElement(uri, localName, qName, attributes);
// book元素
if (qName.equals("book")) {
// 初始化book对象
book = new Book();
// 设置book元素的属性
for (int i = 0; i & attributes.getLength(); i++) {
if (attributes.getQName(i).equals("id"))
book.setId(Integer.parseInt(attributes.getValue(i)));
public void endElement(String uri, String localName, String qName) throws SAXException {
super.endElement(uri, localName, qName);
// book元素
if (qName.equals("book")) {
// 添加解析的一本书
this.books.add(book);
// 清空变量
// 设置书的属性
switch (qName) {
case "name":
this.book.setName(textContent);
case "author":
this.book.setAuthor(textContent);
case "year":
this.book.setYear(Integer.parseInt(textContent));
case "price":
this.book.setPrice(Double.parseDouble(textContent));
case "language":
this.book.setLanguage(textContent);
public void characters(char[] ch, int start, int length) throws SAXException {
super.characters(ch, start, length);
// 获得文本的内容
this.textContent = new String(ch, start, length);
2.2定义SAX类,用于解析XML文档
package com.imooc.
import java.io.F
import java.io.IOE
import java.util.ArrayL
import javax.xml.parsers.ParserConfigurationE
import javax.xml.parsers.SAXP
import javax.xml.parsers.SAXParserF
import org.xml.sax.SAXE
import com.imooc.book.B
* 以SAX方式解析XML文档
* @author Administrator
public class SAX {
* @param path
XML文档路径
* @return 解析XML文档,并存储在ArrayList列表中
public static ArrayList&Book& parseXML(String path) {
// 创建 一个SAXParserFactory对象
SAXParserFactory factory = SAXParserFactory.newInstance();
// 声明一个SAXParser对象
// 创建一个Handler对象
Handler handler = new Handler();
// 初始化SAXParser对象
parser = factory.newSAXParser();
// 解析XML文档
parser.parse(new File(path), handler);
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
// 返回读取到的书籍
return handler.getBooks();
3、定义DOM类,使用DOM方式(将ArrayList对象的属性)生成XML文档
package com.imooc.
import java.io.F
import java.io.IOE
import java.util.ArrayL
import javax.xml.parsers.DocumentB
import javax.xml.parsers.DocumentBuilderF
import javax.xml.parsers.ParserConfigurationE
import javax.xml.transform.OutputK
import javax.xml.transform.T
import javax.xml.transform.TransformerConfigurationE
import javax.xml.transform.TransformerE
import javax.xml.transform.TransformerF
import javax.xml.transform.dom.DOMS
import javax.xml.transform.stream.StreamR
import org.w3c.dom.D
import org.w3c.dom.E
import com.imooc.book.B
* 以DOM方式生成XML文档
* 1.创建DocumentBuilderFactory对象
* 2.创建DocumentBuilder对象
* 3.创建Document对象
* 4.设置对象document的声明standalone
* 5.创建元素
* 6.创建TransformerFactory对象
* 7.创建Transformer对象
* 8.设置XML文档的格式
* 9.使用transform方法以字节流写XML文档
* @author Administrator
public class DOM {
* @param books
XML文档的内容
* @param path
生成的XML文档路径
public static void genXML(ArrayList&Book& books, String path) {
// 创建一个DocumentBuilderFactory对象
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
// 创建一个DocumentBuilder对象
DocumentBuilder db = dbf.newDocumentBuilder();
// 创建一个Document对象
Document document = db.newDocument();
// 设置standAlone
document.setXmlStandalone(true);
// 创建根节点
Element bookStore = document.createElement("bookstore");
// 遍历书籍books
for (Book oneBook : books) {
// 创建book元素
Element book = document.createElement("book");
// 将元素book添加到元素bookstore下
bookStore.appendChild(book);
// name元素
if (oneBook.getName() != null && !oneBook.getName().trim().equals("")) {
// 创建name元素
Element name = document.createElement("name");
// 设置name元素的文本内容
name.setTextContent(oneBook.getName());
// 添加name元素
book.appendChild(name);
// author元素
if (oneBook.getAuthor() != null && !oneBook.getAuthor().trim().equals("")) {
// 创建author元素
Element author = document.createElement("author");
// 设置author元素的文本内容
author.setTextContent(oneBook.getAuthor());
// 添加author元素
book.appendChild(author);
// year元素
if (Integer.toString(oneBook.getYear()) != null
&& !Integer.toString(oneBook.getYear()).trim().equals("")) {
// 创建year元素
Element year = document.createElement("year");
// 设置year元素的文本内容
year.setTextContent(Integer.toString(oneBook.getYear()));
// 添加year元素
book.appendChild(year);
// price元素
if (Double.toString(oneBook.getPrice()) != null
&& !Double.toString(oneBook.getPrice()).trim().equals("")) {
// 创建price元素
Element price = document.createElement("price");
// 设置price元素的文本内容
price.setTextContent(Double.toString(oneBook.getPrice()));
// 添加price元素
book.appendChild(price);
// language元素
if (oneBook.getLanguage() != null && !oneBook.getLanguage().trim().equals("")) {
// 创建language元素
Element language = document.createElement("language");
// 设置language元素的文本内容
language.setTextContent(oneBook.getLanguage());
// 添加language元素
book.appendChild(language);
// 将根节点加入到document中
document.appendChild(bookStore);
// 创建一个TransformerFactory对象
TransformerFactory tff = TransformerFactory.newInstance();
// 创建一个Transformer对象
Transformer transformer = tff.newTransformer();
// 设置XML文件“换行”
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
// 设置XML文档的编码
transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
// 创建一个文件对象file
File file = new File(path);
// 如果上级目录不存在,则创建上级目录
if (!file.getParentFile().exists())
file.getParentFile().mkdirs();
// 如果文件不存在,则创建文件
if (!file.exists())
file.createNewFile();
// document内容写通过输出流XML文档
transformer.transform(new DOMSource(document), new StreamResult(file));
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (TransformerConfigurationException e) {
e.printStackTrace();
} catch (TransformerException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
4、定义SAX类,使用SAX方式生成XML文档
package com.imooc.
import java.io.F
import java.io.IOE
import java.util.ArrayL
import javax.xml.transform.OutputK
import javax.xml.transform.T
import javax.xml.transform.TransformerConfigurationE
import javax.xml.transform.sax.SAXTransformerF
import javax.xml.transform.sax.TransformerH
import javax.xml.transform.stream.StreamR
import org.xml.sax.SAXE
import org.xml.sax.helpers.AttributesI
import com.imooc.book.B
* 以SAX方式生成XML文档
* 1.创建SAXTransformerFactory对象
* 2.创建TransformerHandler对象
* 3.创建Transformer对象,用于设置XML文档的格式
* 4.添加元素,属性和文本内容
* 注意:元素的属性由类AttributesImpl对象设置
* @author Administrator
public class SAX {
* @param books
XML文档的内容
* @param path
生成的XML文档路径
public static void genXML(ArrayList&Book& books, String path) {
// 创建一个SAXTransformerFactory对象
SAXTransformerFactory factory = (SAXTransformerFactory) SAXTransformerFactory.newInstance();
// 创建一个TransformerHandler对象
TransformerHandler handler = factory.newTransformerHandler();
// 创建一个Transformer对象
Transformer format = handler.getTransformer();
// 设置XML文档“换行”
format.setOutputProperty(OutputKeys.INDENT, "yes");
// 设置XML文档的编码
format.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
// 创建一个文件对象file
File file = new File(path);
// 如果上级目录不存在,则创建上级目录
if (!file.getParentFile().exists())
file.getParentFile().mkdirs();
// 如果文件不存在,则创建文件
if (!file.exists())
file.createNewFile();
// 以字节流形式写XML文档
handler.setResult(new StreamResult(file));
// 创建一个AttributesImpl对象
AttributesImpl atts = new AttributesImpl();
// XML文档开始
handler.startDocument();
// 根节点开始标签
handler.startElement("", "", "bookstore", atts);
for (Book oneBook : books) {
// 清空属性
atts.clear();
// 添加book标签的属性
if (Integer.toString(oneBook.getId()) != null && !Integer.toString(oneBook.getId()).trim().equals(""))
atts.addAttribute("", "", "id", "", Integer.toString(oneBook.getId()));
// book元素开始标签
handler.startElement("", "", "book", atts);
// name元素
if (oneBook.getName() != null && !oneBook.getName().trim().equals("")) {
// 清空属性
atts.clear();
// name元素开始标签
handler.startElement("", "", "name", atts);
// 设置name元素的文本内容
handler.characters(new String(oneBook.getName()).toCharArray(), 0, oneBook.getName().length());
// name元素结束标签
handler.endElement("", "", "name");
// author元素
if (oneBook.getAuthor() != null && !oneBook.getAuthor().trim().equals("")) {
// 清空属性
atts.clear();
// author元素开始标签
handler.startElement("", "", "author", atts);
// 设置author元素的文本内容
handler.characters(new String(oneBook.getAuthor()).toCharArray(), 0, oneBook.getAuthor().length());
// author元素结束标签
handler.endElement("", "", "author");
// year元素
if (Integer.toString(oneBook.getYear()) != null
&& !Integer.toString(oneBook.getYear()).trim().equals("")) {
// 清空属性
atts.clear();
// year元素开始标签
handler.startElement("", "", "year", atts);
// 设置year元素的文本内容
handler.characters(new String(Integer.toString(oneBook.getYear())).toCharArray(), 0,
Integer.toString(oneBook.getYear()).length());
// year元素结束标签
handler.endElement("", "", "year");
// price元素
if (Double.toString(oneBook.getPrice()) != null
&& !Double.toString(oneBook.getPrice()).trim().equals("")) {
// 清空属性
atts.clear();
// price元素开始标签
handler.startElement("", "", "price", atts);
// 设置price元素的文本内容
handler.characters(new String(Double.toString(oneBook.getPrice())).toCharArray(), 0,
Double.toString(oneBook.getPrice()).length());
// price元素结束标签
handler.endElement("", "", "price");
// language元素
if (oneBook.getLanguage() != null && !oneBook.getLanguage().trim().equals("")) {
// 清空属性
atts.clear();
// language元素开始标签
handler.startElement("", "", "language", atts);
// 设置language元素的文本内容
handler.characters(new String(oneBook.getLanguage()).toCharArray(), 0,
oneBook.getLanguage().length());
// language元素结束标签
handler.endElement("", "", "language");
// book元素结束标签
handler.endElement("", "", "book");
// 根节点结束标签
handler.endElement("", "", "bookstore");
// XML文档结束
handler.endDocument();
} catch (TransformerConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
5、定义JDOM类,使用JDOM方式生成XML文档
package com.imooc.
import java.io.F
import java.io.FileNotFoundE
import java.io.FileOutputS
import java.io.IOE
import java.util.ArrayL
import org.jdom2.D
import org.jdom2.E
import org.jdom2.output.F
import org.jdom2.output.XMLO
import com.imooc.book.B
* 以JDOM方式生成XML文档
* 1.将元素添加到Document对象中
* 2.通过Format的getPrettyFormat()方法创建一个Format对象,用于设置XML文档的格式
* 3.创建一个XMLOutputter对象,关联Format对象
* 4.使用类XMLOutputter中的output方法写XML文档
* @author Administrator
public class JDOM {
* @param books
XML文档的内容
* @param path
生成的XML文档路径
public static void genXML(ArrayList&Book& books, String path) {
// 创建bookstore元素
Element bookStore = new Element("bookstore");
for (Book oneBook : books) {
// 创建book元素
Element book = new Element("book");
// book标签的属性
if (Integer.toString(oneBook.getId()) != null && !Integer.toString(oneBook.getId()).trim().equals(""))
// 设置book标签的属性
book.setAttribute("id", Integer.toString(oneBook.getId()));
// name元素
if (oneBook.getName() != null && !oneBook.getName().trim().equals("")) {
// 创建name元素
Element name = new Element("name");
// 设置name元素的内容
name.setText(oneBook.getName());
// 将name元素添加到book元素下
book.addContent(name);
// author元素
if (oneBook.getAuthor() != null && !oneBook.getAuthor().trim().equals("")) {
// 创建author元素
Element author = new Element("author");
// 设置author元素的内容
author.setText(oneBook.getAuthor());
// 将author元素添加到book元素下
book.addContent(author);
// year元素
if (Integer.toString(oneBook.getYear()) != null && !Integer.toString(oneBook.getYear()).trim().equals("")) {
// 创建year元素
Element year = new Element("year");
// 设置year元素的内容
year.setText(Integer.toString(oneBook.getYear()));
// 将year元素添加到book元素下
book.addContent(year);
// price元素
if (Double.toString(oneBook.getPrice()) != null && !Double.toString(oneBook.getPrice()).trim().equals("")) {
// 创建price元素
Element price = new Element("price");
// 设置price元素的内容
price.setText(Double.toString(oneBook.getPrice()));
// 将price元素添加到book元素下
book.addContent(price);
// language元素
if (oneBook.getLanguage() != null && !oneBook.getLanguage().trim().equals("")) {
// 创建language元素
Element language = new Element("language");
// 设置language元素的内容
language.setText(oneBook.getLanguage());
// 将language元素添加到book元素下
book.addContent(language);
// 将book元素添加到bookstore元素下
bookStore.addContent(book);
// 创建一个Document对象
Document document = new Document(bookStore);
// 创建一个Format对象
Format format = Format.getPrettyFormat();
// 设置XML文档编码
format.setEncoding("UTF-8");
// 设置XML文档“换行”
format.setIndent("");
// 创建一个XMLOutputter对象
XMLOutputter out = new XMLOutputter(format);
// 创建一个文件对象file
File file = new File(path);
// 如果上级目录不存在,则创建上级目录
if (!file.getParentFile().exists())
file.getParentFile().mkdirs();
// 如果文件不存在,则创建文件
if (!file.exists())
file.createNewFile();
// 以字节流写XML文档
out.output(document, new FileOutputStream(file));
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
public static void main(String[] args) {
JDOM.genXML(com.imooc.parse.SAX.parseXML("src/res/books.xml"), "src/res/jdom.xml");
6、定义DOM4J类,使用DOM4J方式生成XML文档
package com.imooc.dom4j;
import java.io.F
import java.io.FileOutputS
import java.io.IOE
import java.util.ArrayL
import org.dom4j.D
import org.dom4j.DocumentH
import org.dom4j.E
import org.dom4j.io.OutputF
import org.dom4j.io.XMLW
import com.imooc.book.B
* 以DOM4J方式生成XML文档
* 1.通过DocumentHelper类的createDocument()方法创建一个Document对象
* 2.添加元素
* 3.通过OutputFormat的createPrettyPrint()方法创建一个OutputFormat对象,用于设置XML文档的输出格式
* 4.使用文件输出流和OutputFormat对象,创建一个XMLWriter对象
* 5.XMLWriter对象write方法,将对象document的内容写入XML文档
* 6.关闭资源
* @author Administrator
public class DOM4J {
* @param books
XML文档的内容
* @param path
生成的XML文档路径
public static void genXML(ArrayList&Book& books, String path) {
// 使用DocumentHelper类创建一个Document对象
Document document = DocumentHelper.createDocument();
// 添加根节点bookstore
Element bookStore = document.addElement("bookstore");
for (Book oneBook : books) {
// 创建book元素
Element book = bookStore.addElement("book");
// book标签的属性
if (Integer.toString(oneBook.getId()) != null && !Integer.toString(oneBook.getId()).trim().equals("")) {
// 为book元素添加属性
book.addAttribute("id", Integer.toString(oneBook.getId()));
// name元素
if (oneBook.getName() != null && !oneBook.getName().trim().equals("")) {
// 创建name元素
Element name = book.addElement("name");
// 设置name元素的文本内容
name.setText(oneBook.getName());
// 创建一个文件对象file
File file = new File(path);
// 如果上级目录不存在,则创建上级目录
if (!file.getParentFile().exists())
file.getParentFile().mkdirs();
// 如果文件不存在,则创建文件
if (!file.exists())
file.createNewFile();
// 创建字节输出流FileOutputStream对象
FileOutputStream out = new FileOutputStream(file);
// 创建一个OutputFormat对象(XML以比较友好的格式输出)
OutputFormat format = OutputFormat.createPrettyPrint();
// 设置XML文档编码
format.setEncoding("UTF-8");
// 设置XML文档缩进
format.setIndent(true);
// 创建一个XMLWriter对象
XMLWriter writer = new XMLWriter(out, format);
// 将内容写入XML文档
writer.write(document);
// 释放资源
writer.close();
} catch (IOException e) {
e.printStackTrace();
7、定义Test类,使用JUint方法测试DOM、SAX、JDOM和DOM4J的性能
package com.imooc.
import java.util.ArrayL
import com.imooc.book.B
import com.imooc.dom.DOM;
public class Test {
* 使用JUint4测试DOM、SAX、JDOM和DOM4J生成XML文档的性能 经测试;
* 性能DOM4J & JDOM & DOM & SAX
* 数据量大时,建议使用DOM4J方式,数据量小时,建议使用SAX方式;
* 如果要频繁增、删和改元素,建议使用DOM方式。
@org.junit.Test
public void test() {
// 通过SAX方法获得XML文档的内容,并存储在ArrayList对象中
ArrayList&Book& books = com.imooc.parse.SAX.parseXML("src\\res\\books.xml");
// 开始时间
Long start = System.currentTimeMillis();
// 使用DOM方式写XML文档
DOM.genXML(books, "src\\res\\dom.xml");
// 结束时间
Long end = System.currentTimeMillis();
// DOM耗时
System.out.println("DOM用时:" + (end - start) + "ms.");
// 开始时间
start = System.currentTimeMillis();
// 使用SAX方式写XML文档
DOM.genXML(books, "src\\res\\sax.xml");
// 结束时间
end = System.currentTimeMillis();
// SAX耗时
System.out.println("SAX用时:" + (end - start) + "ms.");
// 开始时间
start = System.currentTimeMillis();
// 使用JDOM方式写XML文档
DOM.genXML(books, "src\\res\\jdom.xml");
// 结束时间
end = System.currentTimeMillis();
// JDOM耗时
System.out.println("JDOM用时:" + (end - start) + "ms.");
// 开始时间
start = System.currentTimeMillis();
// 使用DOM4J方式写XML文档
DOM.genXML(books, "src\\res\\dom4j.xml");
// 结束时间
end = System.currentTimeMillis();
// DOM4J耗时
System.out.println("DOM4J用时:" + (end - start) + "ms.");
相关标签:
分享即可 +1积分
请登录后,发表评论
评论(Enter+Ctrl)
评论加载中...
评论加载中...
JAVA开发工程师
这位童鞋很懒,什么也没有留下~~!
作者的热门手记
Copyright (C)
All Rights Reserved | 京ICP备 号-2}

我要回帖

更多关于 dom4j sax解析 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信