六,Android Xml解析
在Android程序中,Xml解析与Java中几乎相同,最常用的有SAX,DOM,PULL 三种解析方式。Android中内置了pull解析方式。这也是android推荐的解析方式。下面我们就看下这三种的用法,与不同
1)SAX:(Simple API for XML)这种解析方式基于事件的模型。通俗的讲就是XML文件在加载的过程中,加载到不同节点会相应触发不同方法来处理。它属于一次加载。它可以处理任意大小的XML文件,它对内存的要求非常低,因为SAX采用的是读取文件的方式,也就是当它是文本文件在读,读完就完了,什么信息都没有保存。当然它也有其缺点,解析过程中无法中断,只能读取XML文件而不能修改,编码上也相对复杂与难于理解。它的常用方法:
void startDocument()//文档开始时触发该方法
void endDocument()//文档结束时
void startElement(String uri, String localName, String qName, Attributes atts)//元素开始
void endElement(String uri, String localName, String qName)//元素结束
void characters(char[ ] ch, int start, int length)//文本节点
创建SAX解析器:
(1)用系统默认值来创建一个XMLReader(解析器):
XMLReader reader = XMLReaderFactory.createXMLReader();
(2)从给定的类名称来创建一个XMLReader :
XMLReader reader = XMLReaderFactory.createXMLReader("org.apache.xerces.parsers.SAXParser");
(3)使用javax.xml.parsers包中的SAXParserFactory类和SAXParser类创建:
SAXParserFactory spFactory = SAXParserFactory.newInstance();
SAXParser sParser = spFactory.newSAXParser();
2)DOM:(Document Object Model)文档对象模型,它是基于对象的,又或者基于树的。它属于两次加载,首先把文档载入内存,第二次把文档解析形成一棵树。如果文档过大对内存占用是很大的。但它也有其优点,它可以解析的过程中修改文件树,可以随便存储文件树的任意部分,相对容易理解。
3)Pull解析:android中内置了pull解析包。这也是android程序中所推荐的xml解析方式。从它的字面上就可以看出来,其优点,pull,拉的意思。我要什么资源我就拿什么资源。我只需要xml文件中一部分,我就拉一部分。从而节省资源,提高效率。当然在J2EE中也可以使用Pull解析。Pull解析也非常易于理解。
先上图:
我们就用这三种方式对同一个XML文件进行解析:
<?xml version="1.0"?> <persons> <person id="1"> <name>tom</name> <age>13</age> </person> <person id="2"> <name>jerry</name> <age>14</age> </person> <person id="3"> <name>john</name> <age>34</age> </person> </persons>
SAX解析代码:
package com.iteye.androidtoast.resolver; import java.io.InputStream; import java.util.ArrayList; import java.util.List; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; import android.util.Log; import com.iteye.androidtaost.model.Person; import com.iteye.androidtaost.service.ParseService; public class Sax implements ParseService{ /*SAX解析,是基于事件的,一次性加载*/ private SAXParser parser; public Sax(){ //实例化解析工厂 SAXParserFactory f=SAXParserFactory.newInstance(); try { parser=f.newSAXParser(); } catch (Exception e) { e.printStackTrace(); Log.i("Sax",e.getMessage()); } } @Override public List<Person> doParse(InputStream in) { XmlHandler h=new XmlHandler(); try { parser.parse(in, h); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } return h.getPersons(); } /* * 处理器 */ class XmlHandler extends DefaultHandler{ List<Person> persons=null; private Person p; private Object currentEleName; /** * 开始解析文档的时候实例化集合 */ @Override public void startDocument() throws SAXException { persons=new ArrayList<Person>(); } @Override public void endDocument() throws SAXException { // TODO Auto-generated method stub super.endDocument(); } /** * 元素开始 */ @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { if("person".equals(localName)){ p = new Person();//节点开始的时候实例化person p.id=new Integer(attributes.getValue(0));//得到ID }else if("name".equals(localName)){ this.currentEleName="name"; }else if("age".equals(localName)){ this.currentEleName="age"; } } /** * 元素结束事件 */ @Override public void endElement(String uri, String localName, String qName) throws SAXException { //解析到文档末尾 if("person".equals(localName)){ //将解析完成的对象添加到集合 persons.add(p); }else if("name".equals(localName)||"age".equals(localName)){ this.currentEleName=""; } } /**) * 用户处理字符节点 */ @Override public void characters(char[] ch, int start, int length) throws SAXException { String str=new String(ch,start,length); if("name".equals(currentEleName)){ p.name=str; }else if("age".equals(currentEleName)){ p.age=new Integer(str); } } public List<Person> getPersons(){ return persons; } } }
DOM解析代码:
package com.iteye.androidtoast.resolver; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.List; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NodeList; import org.xml.sax.SAXException; import com.iteye.androidtaost.model.Person; import com.iteye.androidtaost.service.ParseService; /* * DOM解析 */ public class Dom implements ParseService{ /** * 文档构建器 */ private DocumentBuilder builder; private Person person; public Dom(){ //获取构建器 DocumentBuilderFactory f=DocumentBuilderFactory.newInstance(); try { builder=f.newDocumentBuilder(); } catch (ParserConfigurationException e) { e.printStackTrace(); } } @Override public List<Person> doParse(InputStream in) { List<Person> persons=new ArrayList<Person>(); try { Document doc=builder.parse(in); NodeList list=doc.getElementsByTagName("person"); for(int i=0;i<list.getLength();i++){ //提取Person元素 Element el=(Element) list.item(i); person = new Person(); //获取ID节点 person.id=new Integer(el.getAttribute("id")); person.name=getSubelementTextContentByName(el,"name"); person.age=new Integer(getSubelementTextContentByName(el,"age")); persons.add(person); } return persons; } catch (SAXException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return null; } /** * 得到指定元素的子元素文本 节点( * @param el 父元素 * @param name 子元素名称 * @return */ private String getSubelementTextContentByName(Element el, String name) { NodeList list=el.getElementsByTagName(name); Element e=(Element) list.item(0); return e.getTextContent(); } }
Pull解析代码:
package com.iteye.androidtoast.resolver; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.List; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import android.util.Xml; import com.iteye.androidtaost.model.Person; import com.iteye.androidtaost.service.ParseService; public class Pull implements ParseService{ private String tagName; @Override public List<Person> doParse(InputStream in) { List<Person> persons=null; Person person=null; XmlPullParser parser=Xml.newPullParser(); try { parser.setInput(in, "utf-8"); //获取事件类型 int eventType=parser.getEventType(); while(eventType!=XmlPullParser.END_DOCUMENT){ switch(eventType){ //文档开始 case XmlPullParser.START_DOCUMENT: persons=new ArrayList<Person>(); break; case XmlPullParser.START_TAG: tagName = parser.getName(); if("person".equals(tagName)){ person=new Person(); person.id=new Integer(parser.getAttributeValue(0)); }else if("name".equals(tagName)){ person.name=parser.nextText(); }else if("age".equals(tagName)){ person.age=new Integer(parser.nextText()); } break; case XmlPullParser.END_TAG: if("person".equals(parser.getName())){ persons.add(person); } break; } eventType=parser.next(); } } catch (XmlPullParserException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } return persons; } }
上一篇: 大数据存储管理分析:分隔的存储系统
下一篇: xiaomi OJ第17题