博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android简化xml sax解析
阅读量:5067 次
发布时间:2019-06-12

本文共 9401 字,大约阅读时间需要 31 分钟。

  dom解析占用内存大(我这边需要解析各种各样的kml文件,有时4-5M的kml文件使用dom解析很多手机就内存溢出了),也需要引入第三方库,所以使用相对于节省内存很多、不需引入其他库的sax解析就是很好的选择了。因为sax解析比较复杂的xml文件特别麻烦,所以整理了一个简化android sax解析的工具。

  实现思路:和Android Touch事件传递机制一样,把需要子解析器解析的节点往下传递。

  如果有进一步简化的方法,欢迎交流!email:csqwyyx@163.com。

  示例程序:https://github.com/John-Chen/EasySaxParser

 

  简化工具SaxParser:

public abstract class SaxParser {    protected String curQName;    protected StringBuilder curValue = new StringBuilder();    protected SaxParser saxParser;    protected String saxParserQName;    /**     * 需要生成子SaxParser的节点名称     */    protected HashSet
childParserQNames; public SaxParser() { } public SaxParser(HashSet
childParserQNames) { this.childParserQNames = childParserQNames; } protected void startElement(String uri, String localName, String qName, Attributes attributes) { if(qName == null){ return; } if(saxParser != null){ saxParser.startElement(uri, qName, qName, attributes); }else if(childParserQNames != null && childParserQNames.contains(qName)){ this.saxParser = dispatchTo(qName, attributes); if(this.saxParser != null){ this.saxParserQName = qName; saxParser.parserStart(attributes); } }else{ curQName = qName; if(curValue.length() > 0){ curValue.delete(0, curValue.length()); } } } protected void endElement(String uri, String localName, String qName) { if(qName == null){ return; } if(qName.equals(saxParserQName)){ if(saxParser != null){ saxParser.parserEnd(); } saxParser = null; saxParserQName = null; }else if(saxParser != null){ saxParser.endElement(uri, qName, qName); }else{ parserElementEnd(qName, curValue.toString()); curQName = null; if(curValue.length() > 0){ curValue.delete(0, curValue.length()); } } } protected void characters(char[] ch, int start, int length) { if(saxParser != null){ saxParser.characters(ch, start, length); }else{ String data = new String(ch, start, length); if(data.length() > 0 && curQName != null){ curValue.append(data); } } } /** * 开始解析一个输入流 * @param is 文件输入流 * @param rootParserQName 解析的文件根节点 * @param rootParser 根解析器 */ public static void start(InputStream is, final String rootParserQName, final SaxParser rootParser){ try { SAXParser parser = SAXParserFactory.newInstance().newSAXParser(); parser.parse(is, new DefaultHandler(){ @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { if(qName == null){ return; } if(rootParser != null){ rootParser.startElement(uri, qName, qName, attributes); }else if(qName.equals(rootParserQName)){ rootParser.parserStart(attributes); } } @Override public void characters(char[] ch, int start, int length) throws SAXException { if(rootParser != null){ rootParser.characters(ch, start, length); } } @Override public void endElement(String uri, String localName, String qName) throws SAXException { if(qName == null){ return; } if(qName.contains(rootParserQName)){ if(rootParser != null){ rootParser.parserEnd(); } }else if(rootParser != null){ rootParser.endElement(uri, qName, qName); } } }); } catch (Exception e) { e.printStackTrace(); } } /** * 节点解析开始 */ public abstract void parserStart(Attributes attributes); /** * 一个子节点解析结束 * @param value characters获得的值 */ public abstract void parserElementEnd(String qName, String value); /** * 解析事件需要向下传递,返回需要传递的子SaxParser */ public abstract SaxParser dispatchTo(String qName, Attributes attributes); /** * 节点解析结束 */ public abstract void parserEnd();}

 

需要解析的xml文件test.xml:

abc
csq
293156
8
深圳湾公园
2015-03-21T10:00:13Z
113.93946,22.48955,9.0

   

开始解析:

根节点kml,根节点解析器KmlParser

SaxParser.start(getAssets().open("test.kml"), "kml", new Kml.KmlParser(kml));

 

部分节点解析实现:

public static class KmlParser extends SaxParser {        private Kml kml;        public KmlParser(Kml kml) {            super(new HashSet
()); this.kml = kml; childParserQNames.add("Document"); } @Override public void parserStart(Attributes attributes) { } @Override public void parserElementEnd(String qName, String value) { } @Override public SaxParser dispatchTo(String qName, Attributes attributes) { if(qName.equals("Document")){ return new Document.DocumentParser(kml); } return null; } @Override public void parserEnd() { } }

  

public static class DocumentParser extends SaxParser {        private Kml kml;        private Document document;        public DocumentParser(Kml kml) {            super(new HashSet
()); this.kml = kml; childParserQNames.add("ExtendedData"); childParserQNames.add("Placemark"); } @Override public void parserStart(Attributes attributes) { document = new Document(); document.id = attributes.getValue("id"); } @Override public void parserElementEnd(String qName, String value) { if(document == null){ return; } if(qName.equals("description")){ document.description = value; }else if(qName.equals("author")){ document.author = value; } } @Override public SaxParser dispatchTo(String qName, Attributes attributes) { if(document == null){ return null; } if(qName.equals("ExtendedData")){ return new ExtendedData.ExtendedDataParser(document); }else if(qName.equals("Placemark")){ return new Placemark.PlacemarkParser(document); } return null; } @Override public void parserEnd() { kml.document = document; } }

  

public static class PlacemarkParser extends SaxParser {        private Document document;        private Placemark placemark;        public PlacemarkParser(Document document) {            super(new HashSet
(1)); childParserQNames.add("Point"); this.document = document; } @Override public void parserStart(Attributes attributes) { placemark = new Placemark(); } @Override public void parserElementEnd(String qName, String value) { if(qName.equals("name")){ placemark.name = value; }else if(qName.equals("when")){ placemark.when = value; } } @Override public SaxParser dispatchTo(String qName, Attributes attributes) { if(qName.equals("Point")){ return new Point.PointParser(placemark); } return null; } @Override public void parserEnd() { document.placemark = placemark; } }

  

public static class ExtendedDataParser extends SaxParser {        private Document document;        private ExtendedData extendedData;        public ExtendedDataParser(Document document) {            super(new HashSet
(1)); childParserQNames.add("Data"); this.document = document; } @Override public void parserStart(Attributes attributes) { extendedData = new ExtendedData(); } @Override public void parserElementEnd(String qName, String value) { } @Override public SaxParser dispatchTo(String qName, Attributes attributes) { if(qName.equals("Data")){ return new Data.DataParser(extendedData); } return null; } @Override public void parserEnd() { document.extendedDatas = extendedData; } }

  

......

 

解析结果:

 

  

 

转载于:https://www.cnblogs.com/John-Chen/p/4644103.html

你可能感兴趣的文章
IE6中 PNG 背景透明的最佳解决方案
查看>>
easyui设置行的背景色
查看>>
JavaScript学习总结【8】、面向对象编程
查看>>
【HackerRank】Gem Stones
查看>>
Octopress技巧之设置关键字和描述
查看>>
ajax学习
查看>>
数据库的优化
查看>>
【转】tar打包解压详解
查看>>
【hadoop】【demo】HBase shell
查看>>
GTK: about Building GTK+ 3.0
查看>>
MySQL 5.7的安装及主从复制(主从同步)
查看>>
互联网公司站点通病之弱口令
查看>>
python file的3中读法
查看>>
Linux下二进制包、源代码包、rpm包
查看>>
线型网络
查看>>
Xml帮助类
查看>>
jQuery 学习--事件
查看>>
spring scheduled
查看>>
IOS-objectForKey与valueForKey在NSDictionary中的差异
查看>>
本地推送通知在iOS8上的不同
查看>>