dom:
通用性强,它会将XML文件的所有内容读取到内存中,然后允许您使用DOM API遍历XML树、检索所需的数据;简单直观,但需要将文档读取到内存,并不太适合移动设备;
sax:
SAX是一个解析速度快并且占用内存少的xml解析 器;采用事件驱动,它并不需要解析整个文档;实现:继承DefaultHandler,覆写startElement、endElement、characters等方法;
pull:
Android自带的XML解析器,和SAX基本类似,也是事件驱动,不同的是PULL事件返回的是数值型;推荐使用。
--------------------------------------------------------------------------
下面介绍pull解析和sax解析xml的方式,dom一般不会在移动设备上使用,故略去。
--------------------------------------------------------------------------
一.pull解析:
1.需要使用的类:
android.util.Xml org.xmlpull.v1.XmlSerializer org.xmlpull.v1.XmlPullParser
2.是否需要额外jar包支持:否
3.使用方式:
1.创建xml:
a. 创建xmlSerializer对象
XmlSerializer serializer = Xml.newSerializer();b.设置输出流
serializer.setOutput(outputstream,encoding)c.开始创建xml文档并添加节点
serializer.startDocument("utf-8",true); serializer.startTag(null,node_name); ... serializer.endTag(null,node_name); serializer.endDocument();
2.解析xml:
a.创建xmlPullParser对象
XmlPullParser parser = Xml.newPullParser();b.设置输入流
parser.setInput(inputstream,encoding);c.解析
int type = parser.getEventType(); while(type != XmlPullParser.END_DOCUMENT) { switch (type) { case XmlPullParser.START_TAG: break; case XmlPullParser.END_TAG: break; } type = parser.next();//一定别忘了这句代码 }4.实例
/** * 使用XmlSerializer生成xml文件 */ private void makeXML() { List<WeatherData> citys = Data.getCityData(); try { File path = Environment.getExternalStorageDirectory(); XmlSerializer serializer = Xml.newSerializer(); serializer.setOutput(new FileOutputStream(new File(path,"weather.xml")),"utf-8"); serializer.startDocument("utf-8",true); serializer.startTag(null,"info"); for(WeatherData city : citys) { serializer.startTag(null,"city"); serializer.attribute(null,"id",city.getId()); serializer.attribute(null,"name",city.getName()); serializer.startTag(null,"weather"); serializer.text(city.getWeather()); serializer.endTag(null,"weather"); serializer.startTag(null,"temp"); serializer.text(city.getTemp()); serializer.endTag(null,"temp"); serializer.startTag(null,"wind"); serializer.text(city.getWind()); serializer.endTag(null,"wind"); serializer.endTag(null,"city"); } serializer.endTag(null,"info"); serializer.endDocument(); } catch (Exception e) { e.printStackTrace(); Toast.makeText(this, "保存失败",0).show(); } }pull解析xml:
//返回List<Map<String,String>>方便SimpleAdapter设置数据源 public static List<Map<String,String>> getWeatherData(File file) { if(file == null) return null; XmlPullParser parser = Xml.newPullParser(); List<Map<String,String>> list = null; Map<String,String> map = null; try { parser.setInput(new FileInputStream(file),"utf-8"); int type = parser.getEventType(); while(type != XmlPullParser.END_DOCUMENT) { switch (type) { case XmlPullParser.START_TAG: if("info".equals(parser.getName())) { list = new ArrayList<Map<String,String>>(); }else if("city".equals(parser.getName())) { map = new HashMap<String, String>(); map.put("city",parser.getAttributeValue(null,"name")); }else if("weather".equals(parser.getName())) { map.put("weather",parser.nextText()); }else if("temp".equals(parser.getName())) { map.put("temp",parser.nextText()); }else if("wind".equals(parser.getName())) { map.put("wind",parser.nextText()); } break; case XmlPullParser.END_TAG: if("city".equals(parser.getName())) { list.add(map); map = null; } break; default: break; } type = parser.next(); } } catch (Exception e) { e.printStackTrace(); Log.i(TAG,e.getMessage()); } return list; }待解析的xml文件(下同,天气实体bean对象略):
<info> <city id="1" name="上海"> <weather>晴</weather> <temp>34</temp> <wind>东风</wind> </city> <city id="2" name="北京"> <weather>雷阵雨</weather> <temp>24</temp> <wind>南风</wind> </city> <city id="3" name="南京"> <weather>雨夹雪</weather> <temp>32</temp> <wind>西风</wind> </city> </info>
二、sax解析
1.需要使用的类:
一个自定义的继承org.xml.sax.helpers.DefaultHandler的处理器类 javax.xml.parsers.SAXParserFactory工厂类 javax.xml.parsers.SAXParser类,解析器
2.是否需要扩展jar包:不需要
3.使用方式:
1.根据你要解析的xml定义一个处理器(复写startDocument,startElement,characters,endElement方法):
public class SaxHandler4Weather extends DefaultHandler { @Override public void startDocument() throws SAXException { } @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { } @Override public void endElement(String uri, String localName, String qName) throws SAXException { } @Override public void characters(char[] ch, int start, int length) throws SAXException { } }2.利用解析器工厂,创建解析器对象
SAXParserFactory factory = SAXParserFactory.newInstance(); SAXParser parser = factory.newSAXParser();3.利用自定义的处理器解析xml
parser.parse(file,handler);4.handler处理器对象中应该提供类似getData的方法,利用此方法将解析结果返回。
4.实例:
1.处理器
package cn.edu.chd.xmlutils; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; /** * @author Rowand jj * *解析天气的xml处理器 */ public class SaxHandler4Weather extends DefaultHandler { private Map<String,String> map = null;//存储单个解析的完整对象 private List<Map<String,String>> list = null;//存储所有的解析对象 private String currentTag = null;//正在解析的元素的标签 private String currentValue = null;//解析当前元素的值 private String nodeName = "city";//待解析的xml文件中代表一个实体的xml根节点名 @Override public void startDocument() throws SAXException { list = new ArrayList<Map<String,String>>(); } @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { if(qName.equals(nodeName))//发现city节点 { map = new HashMap<String, String>(); } if(attributes!=null && map!= null) { for(int i = 0; i < attributes.getLength();i++) { if(attributes.getQName(i).equals("name")) { map.put("city", attributes.getValue(i)); } } } currentTag = qName; } @Override public void endElement(String uri, String localName, String qName) throws SAXException { if(qName.equals(nodeName))//一个city节点解析完毕 { list.add(map); map = null; } } @Override public void characters(char[] ch, int start, int length) throws SAXException { if(currentTag!=null && map!=null) { currentValue = new String(ch,start,length).trim(); if(nodeName.equals(currentTag))//city节点 { }else if("weather".equals(currentTag))//是否是weather节点 { map.put("weather", currentValue); }else if("temp".equals(currentTag))//是否是temp节点 { map.put("temp",currentValue); }else if("wind".equals(currentTag))//是否是wind节点 { map.put("wind",currentValue); } } currentTag = null; currentValue = null; } public List<Map<String, String>> getList() { return list; } }2.解析xml:
public static List<Map<String,String>> getWeatherData(File file) { List<Map<String,String>> list = null; try { SAXParserFactory factory = SAXParserFactory.newInstance(); SAXParser parser = factory.newSAXParser(); SaxHandler4Weather handler = new SaxHandler4Weather(); parser.parse(file,handler); list = handler.getList(); Log.i(TAG,"-->size = "+list.size()); } catch (Exception e) { Log.i(TAG,e.getMessage()); } return list; }
------------------------------------------------