安卓下解析xml文件有多种方式:
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;
}
------------------------------------------------