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文件,只需得到文件流即可。
转载于:https://my.oschina.net/u/657400/blog/113380