利用Dom4J的SAXReader解析大文件 - - ITeye技术网站
今天用到了对内容量很大的XML文件的解析,顺便记录一下。
关于XML的解析技术网上有很多文章,不再详述。 主要的方式有JDK自带的JAXP(Java API For XML Parser)、JDom、Dom4j等。其中Dom4J是相当灵活的,很多开源框架都基于Dom4J来做XML解析。
底层的解析器主要有两种: DOM、SAX。 其中DOM作为树型结构将文本装载到内存中,适合文本内容比较小的;SAX则按照流的方式扫描,事件触发的方式供你处理,比如遇到某个结点的开始符,结束符,大文本不能一次性装载到内存中,就应该采用SAX方式。
DOM4J利用SAXReader类来读取文件,然后为SAXReader对象设置元素处理解析器ElementHandler,有doStart和doEnd两个方法,分别在遇到元素的开始符号和结束符号时候触发。只需在相应的方法内实现自己的业务逻辑即可。
例子: XML文件结构如下:
view plaincopy to clipboardprint?<?xml version="1.0" encoding="GB2312"?>
<TESTINFO version="1.0">
<UPDATEINFO>
<PARAM_TIMESTAMP>2010-12-22 09:54:09</PARAM_TIMESTAMP>
<CITYINFO_LIST>
<CITYINFO City="591" Name="XYZ" No="334" />
<CITYINFO City="591" Name="BJD" No="335" />
<CITYINFO City="591" Name="UUS" No="390" />
</CITYINFO_LIST>
</UPDATEINFO>
</TESTINFO>
<?xml version="1.0" encoding="GB2312"?>
<TESTINFO version="1.0">
<UPDATEINFO>
<PARAM_TIMESTAMP>2010-12-22 09:54:09</PARAM_TIMESTAMP>
<CITYINFO_LIST>
<CITYINFO City="591" Name="XYZ" No="334" />
<CITYINFO City="591" Name="BJD" No="335" />
<CITYINFO City="591" Name="UUS" No="390" />
</CITYINFO_LIST>
</UPDATEINFO>
</TESTINFO>
其中CITYINFO可能是个很大的列表。 完整的程序代码如下:
view plaincopy to clipboardprint?package com.atu.xmltest;
import java.io.InputStream;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.ElementHandler;
import org.dom4j.ElementPath;
import org.dom4j.io.SAXReader;
public class MySaxHandler implements ElementHandler {
SAXReader reader;
public MySaxHandler() {
// test.xml文件跟类放在同一目录下
try {
InputStream is = MySaxHandler.class.getResourceAsStream("test.xml");
reader = new SAXReader();
reader.setDefaultHandler(this);
reader.read(is);
} catch (DocumentException e) {
e.printStackTrace();
}
}
@Override
public void onEnd(ElementPath ep) {
Element e = ep.getCurrent(); //获得当前节点
if(e.getName().equals("PARAM_TIMESTAMP"))
System.out.println("解析到时间:"+e.getText());
else if(e.getName().equals("CITYINFO")){
System.out.printf("解析到CITYINFO,属性值为:%s,%s,%s/n", e
.attributeValue("City"), e.attributeValue("Name"), e
.attributeValue("No"));
}
e.detach(); //记得从内存中移去
}
@Override
public void onStart(ElementPath ep) {
}
public static void main(String[] args){
new MySaxHandler();
}
}
package com.atu.xmltest;
import java.io.InputStream;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.ElementHandler;
import org.dom4j.ElementPath;
import org.dom4j.io.SAXReader;
public class MySaxHandler implements ElementHandler {
SAXReader reader;
public MySaxHandler() {
// test.xml文件跟类放在同一目录下
try {
InputStream is = MySaxHandler.class.getResourceAsStream("test.xml");
reader = new SAXReader();
reader.setDefaultHandler(this);
reader.read(is);
} catch (DocumentException e) {
e.printStackTrace();
}
}
@Override
public void onEnd(ElementPath ep) {
Element e = ep.getCurrent(); //获得当前节点
if(e.getName().equals("PARAM_TIMESTAMP"))
System.out.println("解析到时间:"+e.getText());
else if(e.getName().equals("CITYINFO")){
System.out.printf("解析到CITYINFO,属性值为:%s,%s,%s/n", e
.attributeValue("City"), e.attributeValue("Name"), e
.attributeValue("No"));
}
e.detach(); //记得从内存中移去
}
@Override
public void onStart(ElementPath ep) {
}
public static void main(String[] args){
new MySaxHandler();
}
}
运行结果:
解析到时间:2010-12-22 09:54:09
解析到CITYINFO,属性值为:591,XYZ,334
解析到CITYINFO,属性值为:592,BJD,335
解析到CITYINFO,属性值为:593,UUS,390
没有评论:
发表评论