Android XML解析
2016-02-29 22:57
561 查看
Android平台上解析XML文件的方法有三种。
基于事件驱动的解析器,它并不需要解析完整个文档,在按内容顺序(不可倒退)解析文档的过程中,SAX会判断当前读到的字符是否合法XML语法中的某部分,如果符合就会触发事件,调用事件处理器相应的处理方法。
需要重写DefaultHandler的几个方法,
基于树形结构的的节点或信息片段的集合,DOM解析XML文件时会将XML文件的所有内容读取到内存中,然后使用DOM API遍历XML树、检索所需数据。利用DOM中的对象,可以对XML文档进行读取、搜索、修改、添加和删除等操作。
使用DOM操作XML的代码看起来比较直观,并且由于XML所有内容都在内存中以树形结构存放,因此检索和更新效率会更高,但同时内存的消耗比较大,除非需要编辑XML文件或者XML树结构复杂否则不建议使用。
运行方式和SAX类似,也是基于事件的模式,它提供了如开始元素和结束元素等事件(读取到xml的声明返回START_DOCUMENT;
读取到xml的结束返回END_DOCUMENT,读取到xml的开始标签返回START_TAG,读取到xml的结束标签返回END_TAG,读取到xml的文本返回TEXT)
在PULL解析过程中,使用parser.next()迭代遍历节点元素并触发相应事件并产生事件标志(数字),我们可以通过switch对感兴趣的事件进行处理。
SAX解析器的工作方式是自动将事件推入事件处理器进行处理,因此不能控制事件的处理主动结束;而Pull解析器的工作方式为允许你的应用程序代码主动从解析器中获取事件,正因为是主动获取事件,因此可以在满足了需要的条件后不再获取事件,结束解析。Pull解析的过程是一个while循环,随时可以跳出,而SAX解析不是,sax是只要解析了,就必须解析完成,要停只能靠抛SAXException异常了。。
总之推荐用Pull解析,毕竟Android系统内部也是用的PULL解析器解析各种XML的。
SAX解析(Simple API for XML)
基于事件驱动的解析器,它并不需要解析完整个文档,在按内容顺序(不可倒退)解析文档的过程中,SAX会判断当前读到的字符是否合法XML语法中的某部分,如果符合就会触发事件,调用事件处理器相应的处理方法。需要重写DefaultHandler的几个方法,
startDocument()//文档开始,做好准备 startElement(String uri, String localName, String qName, Attributes attributes) characters(char[] ch, int start, int length)//处理文本内容 endElement(String uri, String localName, String qName)当执行文档时遇到起始节点,startElement方法将会被调用,我们可以获取起始节点相关信息;然后characters方法被调用,我们可以获取节点内的文本信息;最后endElement方法被调用,我们可以做收尾的相关操作。
DOM解析(Document Object Model)
基于树形结构的的节点或信息片段的集合,DOM解析XML文件时会将XML文件的所有内容读取到内存中,然后使用DOM API遍历XML树、检索所需数据。利用DOM中的对象,可以对XML文档进行读取、搜索、修改、添加和删除等操作。使用DOM操作XML的代码看起来比较直观,并且由于XML所有内容都在内存中以树形结构存放,因此检索和更新效率会更高,但同时内存的消耗比较大,除非需要编辑XML文件或者XML树结构复杂否则不建议使用。
/* <?xml version="1.0" encoding="UTF-8"?> <persons> <person id="23"> <name>李明</name> <age>30</age> </person> <person id="20"> <name>李向梅</name> <age>25</age> </person> </persons>*/ public static List<Person> readXML(InputStream inStream) { List<Person> persons = new ArrayList<Person>();//设定person实体类有id和name,age try { //取得DocumentBuilderFactory实例 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); //从factory获取DocumentBuilder实例 DocumentBuilder builder = factory.newDocumentBuilder(); Document dom = builder.parse(inStream);//解析输入流 得到Document实例 Element root = dom.getDocumentElement();//得到节点树 NodeList items = root.getElementsByTagName("person");//查找所有person节点 for (int i = 0; i < items.getLength(); i++) { Person person = new Person(); Element personNode = (Element) items.item(i);//得到第一个person节点 person.setId(new Integer(personNode.getAttribute("id")));//获取person节点的id属性值 //获取person节点下的所有子节点(标签之间的空白节点和name/age元素) NodeList childsNodes = personNode.getChildNodes(); for (int j = 0; j < childsNodes.getLength(); j++) { Node node = (Node) childsNodes.item(j); if(node.getNodeType() == Node.ELEMENT_NODE){//判断是否为元素类型 Element childNode = (Element) node; if ("name".equals(childNode.getNodeName())){ //判断是否name元素 //获取name元素下Text节点,然后从Text节点获取或者更新数据,这里只要获胜即可 person.setName(childNode.getFirstChild().getNodeValue()); } else if (“age”.equals(childNode.getNodeName())) { person.setAge(new Short(childNode.getFirstChild().getNodeValue())); } } } persons.add(person); } inStream.close(); } catch (Exception e) { e.printStackTrace(); } return persons; }
PULL解析
运行方式和SAX类似,也是基于事件的模式,它提供了如开始元素和结束元素等事件(读取到xml的声明返回START_DOCUMENT;读取到xml的结束返回END_DOCUMENT,读取到xml的开始标签返回START_TAG,读取到xml的结束标签返回END_TAG,读取到xml的文本返回TEXT)
在PULL解析过程中,使用parser.next()迭代遍历节点元素并触发相应事件并产生事件标志(数字),我们可以通过switch对感兴趣的事件进行处理。
public static List<Person> readXML(InputStream inStream) { try { XmlPullParser parser = Xml.newPullParser();//由android.util.Xml创建一个XmlPullParser实例 parser.setInput(inStream, "UTF-8");//设置输入流 并指明编码方式 Person currentPerson = null; List<Person> persons = null; int eventType = parser.getEventType(); while (eventType != XmlPullParser.END_DOCUMENT) { switch (eventType) { case XmlPullParser.START_DOCUMENT://文档开始事件,可以进行数据初始化处理 persons = new ArrayList<Person>(); break; case XmlPullParser.START_TAG://开始元素事件 String name = parser.getName(); if (name.equalsIgnoreCase("person")) { currentPerson = new Person(); currentPerson.setId(new Integer(parser.getAttributeValue(null, "id")));//获取属性值 } else if (currentPerson != null) { if (name.equalsIgnoreCase("name")) { currentPerson.setName(parser.nextText());// 如果后面是Text元素,即返回它的值 } else if (name.equalsIgnoreCase("age")) { currentPerson.setAge(new Short(parser.nextText())); } } break; case XmlPullParser.END_TAG://结束元素事件 if (parser.getName().equalsIgnoreCase("person") && currentPerson != null) { persons.add(currentPerson); currentPerson = null; } break; } eventType = parser.next(); } inStream.close(); return persons; } catch (Exception e) { e.printStackTrace(); } return null; }
总结
除非需要编辑XML文件或者XML树结构复杂否则不建议使用DOM解析。SAX解析器的工作方式是自动将事件推入事件处理器进行处理,因此不能控制事件的处理主动结束;而Pull解析器的工作方式为允许你的应用程序代码主动从解析器中获取事件,正因为是主动获取事件,因此可以在满足了需要的条件后不再获取事件,结束解析。Pull解析的过程是一个while循环,随时可以跳出,而SAX解析不是,sax是只要解析了,就必须解析完成,要停只能靠抛SAXException异常了。。
总之推荐用Pull解析,毕竟Android系统内部也是用的PULL解析器解析各种XML的。
相关文章推荐
- Android Ⅰ
- Android资源
- [android] 保存文件到SD卡
- Android 自定义ViewGroup 实战篇 -> 实现FlowLayout
- android性能优化
- Android Studio的基本使用?
- Android开发之Activity的生命周期(一)
- Android init 启动过程分析
- 具有选择功能的对话框(下拉列表对话框)
- N个非常有用的Android程序片段(持续更新)
- 不小心将Android虚拟设备删除了几个属性,如何恢复...
- 【Android 开发教程】动态添加Fragments
- android欢迎界面渐入,渐出效果制作
- android 自定义TopBar的使用
- Android实现上下滑动隐藏/显示工具栏
- Android 集成facebook 第三方登陆
- Android 之 SystemService
- Android Studio ——Android Studio如何集成Genymotion
- android:Notification实现状态栏的通知
- Android之SurfaceView使用总结