最近在解析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。
希望对看到的人有所帮助。
附上参考资料,讲的都很详细: