一直都在使用dom的方式读取xml文件,但如果稍大点的xml文件那么dom方式就有点不太适合。
研究了下jdk的api,用dom和sax方式的解析结果做了个对比
要解析的xml内容格式如下
<?xml version="1.0" encoding="UTF-8"?>
<urlset>
<url>
<loc>商品链接访问地址</loc>
<data>
<display>
<title>商品名称</title>
<price>价格</price>
<image>
商品图片访问地址
</image>
<description>商品描述</description>
<barCode>条形码值</barCode>
<area>产地 (北京)</area>
<producedate>生产日期 (2011-11-11)</producedate>
<manufacturers>生产厂家 (某某某)</manufacturers>
</display>
</data>
</url>
//.....更更多
</urlset>
xml文件大小16.5M
首先是dom方式读取,代码如下
package test.xml;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
public class JDKBigXmlDomParse {
private int statmentSize = 6;
private List<Map<String, Object>> dataList = new ArrayList<Map<String, Object>>(statmentSize);
public void test() throws Exception{
String uri = "f:\\test.xml";
Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(uri);
NodeList urls = doc.getElementsByTagName("url");
int length = urls.getLength();
for(int i=0;i<length;i++){
Node node = urls.item(i);
if(node.getNodeType() != Node.ELEMENT_NODE){
continue;
}
Element urlElement = (Element)node;
Map<String,Object> entry = parseEntity(urlElement);
if(!entry.isEmpty()){
dataList.add(entry);
if(dataList.size() == statmentSize){
doSomeThing();
}
}
}
}
private Map<String,Object> parseEntity(Element element){
Map<String,Object> map = new HashMap<String, Object>();
map.put("loc", getElementValueByTagName(element,"loc"));
map.put("title", getElementValueByTagName(element,"title"));
map.put("price", getElementValueByTagName(element,"price"));
map.put("image", getElementValueByTagName(element,"image"));
map.put("description", getElementValueByTagName(element,"description"));
map.put("barCode", getElementValueByTagName(element,"barCode"));
map.put("area", getElementValueByTagName(element,"area"));
map.put("producedate", getElementValueByTagName(element,"producedate"));
map.put("manufacturers", getElementValueByTagName(element,"manufacturers"));
return map;
}
private String getElementValueByTagName(Element element,String tagName){
NodeList nodeList = element.getElementsByTagName(tagName);
String value = "";
if(nodeList.getLength() != 0){
Node node = nodeList.item(0);
value = node.getFirstChild().getNodeValue().trim();
}
return value;
}
private void doSomeThing(){
//printMapList(dataList);
dataList.clear();
}
private void printMapList(List<Map<String,Object>> dataList){
boolean first = true;
for(Map<String,Object> map:dataList){
System.out.println();
System.out.print("{");
Set<Map.Entry<String, Object>> entries = map.entrySet();
for(Map.Entry<String, Object> entry:entries){
if(!first){
System.out.print(",");
}
System.out.print("\""+entry.getKey()+"\":");
System.out.print("\""+entry.getValue()+"\"");
first = false;
}
first = true;
System.out.print("}");
}
System.out.println();
}
public static void main(String[] args) throws Exception{
long start = System.nanoTime();
new JDKBigXmlDomParse().test();
long end = System.nanoTime();
System.out.println("耗时:"+(end-start)/1000000000.0+"秒");
}
}
运行结果:
耗时:3.212168172秒
sax方式读取,代码如下:
package test.xml;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.apache.commons.lang.StringUtils;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
public class JDKBigXmlSaxParse extends DefaultHandler {
private int statmentSize = 6;
private List<Map<String, Object>> dataList = new ArrayList<Map<String, Object>>(statmentSize);
private Map<String, Object> dataMap;
private String currentTag = "";
public void test() throws Exception {
SAXParser sax = SAXParserFactory.newInstance().newSAXParser();
InputStream in = new FileInputStream("f:\\test.xml");
sax.parse(in, this);
in.close();
}
@Override
public void characters(char[] ch, int start, int length)throws SAXException {
String value = new String(ch, start, length);
if(!StringUtils.isBlank(value)){
dataMap.put(currentTag, value.trim());
}
}
@Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
if("url".equals(qName)){
dataList.add(dataMap);
//dataMap.clear();
}
if(dataList.size() == statmentSize){
doSomeThing();
dataList.clear();
}
if("urlset".equals(qName) && dataList.size() != 0){
doSomeThing();
dataList.clear();
}
}
@Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
if ("url".equals(qName)) {
dataMap = new HashMap<String, Object>();
return;
}
currentTag = qName;
}
public static void main(String[] args) throws Exception {
long start = System.nanoTime();
new JDKBigXmlSaxParse().test();
long end = System.nanoTime();
System.out.println("耗时:"+(end-start)/1000000000.0+"秒");
}
public void doSomeThing(){
//printMapList(dataList);
}
private void printMapList(List<Map<String,Object>> dataList){
boolean first = true;
for(Map<String,Object> map:dataList){
System.out.println();
System.out.print("{");
Set<Map.Entry<String, Object>> entries = map.entrySet();
for(Map.Entry<String, Object> entry:entries){
if(!first){
System.out.print(",");
}
System.out.print("\""+entry.getKey()+"\":");
System.out.print("\""+entry.getValue()+"\"");
first = false;
}
first = true;
System.out.print("}");
}
System.out.println();
}
}
运行结果:
耗时:0.639864769秒
可以看到dom消耗的时间是sax方式的5倍。结论:如果只是读取xml文件,还是sax方式强。。。
而且在eclipse里面用dom方式运行的时候可能会出现eclipse java.lang.OutOfMemoryError: Java heap space这个问题
分享到:
相关推荐
为了深入理解这些概念,你可以参考Java的官方文档,学习每个API的用法,并通过实践编写代码来操作XML文件,例如,创建XML文件,读取XML文件,添加、删除和修改元素,验证XML结构等。同时,也可以查阅DOM4J、JDOM等第...
dom4j因其广泛的API和XPath支持而受到青睐,而jdom则以其Java原生性及性能优势吸引开发者。在你的项目中,你可能需要根据你的XML处理需求、性能要求以及团队的熟悉程度来决定使用哪个库。 在实际应用中,引入`dom4j...
DOM适用于需要频繁查询和修改文档的场景,SAX适用于大文件或内存有限的情况,DOM4J和JDOM则提供了更高级的功能和更好的性能。了解和掌握这些解析方式,对于开发人员来说至关重要,能帮助他们在处理XML数据时做出合适...
本篇文章将详细介绍Java中四种主要的XML解析方法:SAX(Simple API for XML)、DOM(Document Object Model)、DOM4J和JDOM,并通过示例代码展示它们的用法。 1. **SAX解析器**: SAX是一种基于事件驱动的解析方式...
在Android开发中,XML文件常用于存储数据或配置信息,如布局文件、资源文件等。本文将深入探讨如何使用DOM(Document Object Model)解析XML...但请注意,对于大文件,考虑使用SAX或者Pull解析器来优化性能和内存使用。
本资源分别用了四种方式:原生DOM、JDOM、SAX和DOM4J实现的对xml文件的读取,另外还有对excel文件读取与保存的例子,并且资源带有jdom.jar、poi-ooxml.jar和poi-3.7jar包
2. **DOM4J库**:DOM4J是一个非常优秀的Java XML API,它提供了非常方便的API用于解析XML,创建和操作XML文档。通过`SAXReader`可以读取XML文件并将其转换为Document对象,如`doc = new SAXReader().read(file);`。...
除了这两种原生的解析方式,还有很多第三方库提供了更高级的功能,例如Java的JAXB(Java Architecture for XML Binding)用于对象与XML之间的映射,Python的lxml库提供了高效的解析和操作XML的能力。此外,XML ...
1. **DOM API**:与JDOM类似,DOM4J也提供了一个DOM API,可以创建和操作XML文档。 2. **SAX处理**:通过SAXReader,DOM4J能够高效地解析大型XML文件,避免一次性加载整个文档到内存。 3. **XPath支持**:DOM4J支持...
此外,对于复杂XML处理,可以引入Java的DOM解析库如dom4j的iOS版本,它提供了一种更为灵活的方式来操作XML文档。 在实际开发中,选择合适的XML解析方式应根据项目需求来定。如果XML文件较小,且需要频繁地随机访问...
XDK(XML Developer's Kit)是一个工具包,包含了用于创建和操作XML文档的各种工具和库。它为开发者提供了一种简单有效的方式来开发与XML相关的应用。 #### Oracle XML DB概述 Oracle XML DB是Oracle数据库的一个...
5. **E4X(ECMAScript for XML)**:在某些JavaScript环境中,如Flash或旧版的Firefox,支持E4X,它允许直接在JavaScript中嵌入XML,并提供类似于处理JSON的语法来操作XML。然而,E4X在现代浏览器中已不再被支持。 ...
DOM、SAX和StAX是三种主要的XML解析模型。 八、JMX(Java Management Extensions) JMX是一种管理和监控Java应用程序的标准,通过MBean(Managed Beans)和MBeanServer实现。 九、安全 Java Security API提供了...
- **SAX解析**:Simple API for XML,逐行读取XML,事件驱动。当遇到元素开始、结束、属性等时触发回调函数。适合处理大型XML文件,内存占用低,但操作相对复杂。 - **PULL解析**:类似于SAX,也采用事件驱动,但...
而SAX解析器则采用事件驱动的方式,逐行读取,占用内存较少,适用于大文件。 在实际开发中,`Markup`类可能会提供更高级的功能,如XML的写入和修改,或者支持XML Schema(XSD)进行数据验证。理解并熟练使用这类XML...
在C++中解析和操作XML文件,你需要手动处理XML文档的结构,这包括节点、属性和文本。以下是一些关键步骤和知识点: 1. **DOM解析**: - 使用`<xml.dom.minidom>`库:这是C++的标准库的一部分,允许你将整个XML文档...
JDOM-1.1.1的JAR文件是库的主要组成部分,包含所有必要的类和方法,用于读取、写入、构建和操作XML文档。在项目中,你可以通过将这个JAR文件添加到类路径上来使用JDOM的功能。例如,你可以使用`org.jdom.Document`类...
这四种方法各有优缺点,DOM解析方便但占用内存大,SAX和Pull解析节省内存但编程相对复杂,JAXB则提供了对象与XML的直接映射,但可能不适合资源有限的移动环境。在实际开发中,应根据项目需求和资源限制选择合适的XML...
JDOM允许开发者直接通过XML元素名来创建和操作XML文档,相比DOM,JDOM的API更加简洁和直观。 dom4j是另一个流行的Java XML处理库,它不仅支持DOM模型,还提供了SAX和StAX的接口。dom4j的优势在于它的灵活性和强大的...