最近在解析XML时总会遇到比较大的文件,如果使用DOM的方式解析一次装进内存有可能导致OOM Error。因此,尝试采用SAX的流式方式解析了一下,效果还不错。
使用了开源工具DOM4j,其中提供了SAX解析器。
程序实现:
FileReader rd = new FileReader(new File(filePath));
SAXReader reader=new SAXReader();
reader.setEncoding("UTF-8");
XMLHandler handler = new XMLHandler();
reader.addHandler("/data/apps/app/appid", handler);
reader.addHandler("/data/apps/app/category", handler);
reader.read(rd);
首先,创建SAXReader并设定读取文件编码为UTF-8。然后指定并添加解析处理器,因为是流式解析,所以每次解析到对应的标签时就会调用相应的回调方法。XMLHandler实现如下(部分代码):
public class XMLHandler implements ElementHandler {
public void onStart(ElementPath elementPath) {}
public void onEnd(ElementPath elementPath) {
try{
Element row = elementPath.getCurrent();
String path = elementPath.getPath();
if("/data/apps/app/appid".equalsIgnoreCase(path)){
parseElement(row);
}else if("/data/apps/app/category".equalsIgnoreCase(path)){
parseElement(row);
}
}catch(Exception e){
logger.error("onEnd:",e);
}
}
private String parseElement(Element root)throws Exception{
return root.getText();
}
}
其中onStart为遇到开始的标签时回调,onEnd为遇到结束的标签时回调。path为标签对应的xml结构,上面的程序意思就是遇到某个appid或者category的结束标签时,将该标签的Text内容解析出来(之后可以用其它数据结构存储起来)。
xml文件格式:
<data> <apps> <app> <appid>1</appid> <category>游戏</category> </app> </apps> </data>
所以appid对应的路径为:/data/apps/app/appid,category对应的路径为:/data/apps/app/category。
希望对看到的人有所帮助。
附上参考资料,讲的都很详细:
http://xiaoyuclub.iteye.com/blog/865120 dom4j基于sax事件处理
http://ruanchengui1.iteye.com/blog/1140260 dom4j处理xml文件-saxreader与elementhandler的配合