android xml-----Sax解析

来源:互联网 发布:重启apache服务 编辑:程序博客网 时间:2024/04/28 10:53

xml是一种扩展标记语言,是一种简单的数据存储语言,使用一系列简单的标记描述数据。我们在android开发过程会经常用到,特别是解析网络数据,另外还有json格式的数据存储方式,json解析相对xml解析快,流量少,但阅读不太方便,在此我们主要说xml常用的Sax解析,此外xml还有dom、pull两种解析方式。让我们来看一下xml格式的数据结构:

<citys>
    <city>
        <citycode>
101180102
        </citycode>
        <cityName>
巩义
        </cityName>
    </city>
    <city>
        <citycode>
101180103
        </citycode>
        <cityName>
荥阳
        </cityName>
    </city>
    <city>
</citys>

从上面的xml格式的数据看xml其实是有一系列自定义成对的标签和数据组成。我们在才有Hander解析,但我们使用java给DefaultHandler,它实现了Hander的方法,便于我们开发。

让我们看下hander文件格式,在此,我以我以前写的代码为例:

import java.util.ArrayList;
import java.util.List;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;


import com.learn.WeatherInfo.CityrInfo;




public class CityDefautHander extends DefaultHandler
{
private List<CityrInfo> cityrInfos = null;
private  CityrInfo cityrInfo;

StringBuilder stringBuilder1 = null;
StringBuilder stringBuilder2 = null;//会略空的
private String tagName = null;//当前解析的元素标签 ;


public List<CityrInfo> getCityrInfos(){
return cityrInfos;

@Override
public void startDocument() throws SAXException {
cityrInfos= new ArrayList<CityrInfo>();
stringBuilder1 = new StringBuilder();

stringBuilder2 = new StringBuilder();
}



@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
if (localName.equals("city"))
{
cityrInfo = new CityrInfo();
}
this.tagName = localName; 
}


@Override
public void endDocument() throws SAXException {

  super.endDocument();
}


@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
tagName = "" ;
if (localName.equals("city"))
{
cityrInfos.add(cityrInfo);
cityrInfo = null; 
stringBuilder1 = new StringBuilder();
stringBuilder2 = new StringBuilder();
}
}


@Override
public void characters(char[] ch, int start, int length) throws SAXException {

if(tagName!=null){


if (tagName.equals("citycode"))
{
stringBuilder1.append(new String(ch, start, length).trim());
cityrInfo.setCitycode(stringBuilder1.toString());
}else if (tagName.equals("cityName"))
{
stringBuilder2.append(new String(ch, start, length).trim());
cityrInfo.setCityName(stringBuilder2.toString());
}
}
}


}

从上面看,我们可以清楚看到个方法的作用,我们采用StringBuilder ,就是采用StringBuilder具有缓存的作用,可以过滤空的数据,这样我们可以避免有时会因xml数据的格式,而得到的解析为空,实际上我们解析到数据,却得不到数据。


接下来我们同过Sax提供的方法去真正解析获取的数据。代码如下:

public List<CityrInfo> getCityrInfos(){
List<CityrInfo> listInfos = new ArrayList<CityrInfo>();
InputStream input=null;

try
{
input = context.getAssets().open("city.xml");

InputSource source = new InputSource(new InputStreamReader(input, "utf-8"));

SAXParserFactory factory=SAXParserFactory.newInstance();
SAXParser parser = factory.newSAXParser();
CityDefautHander cityDefautHander = new CityDefautHander();

parser.parse(source, cityDefautHander);

listInfos = cityDefautHander.getCityrInfos();
} catch (IOException e)
{
e.printStackTrace();
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
}
   return listInfos;
}
}

Sax解析工厂SAXParserFactory  通过将我们得到xml的数据流,解析到我们所要得到的数据。在上面的代码中,的xml文件,我是放在本地的asserts的目录下。同样,我们要解析网络数据的xml文件,只需得到文件流即可。