【安卓笔记】安卓下xml文件的解析

安卓下解析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;
    }
------------------------------------------------




【安卓笔记】安卓下xml文件的解析

上一篇:Android SQLiteStatement 编译、执行 分析


下一篇:Android 如何设置视频来电的默认铃声