在学习android几天之后,看到Mars老师的视频,而且在网上也查过很多资料,对xml文件的解析稍稍有了一些了解,记录一下,以后自己可以回来卡看。。

首先是解析函数,这个函数传进一个url地址,自己封装一下,以后用的方便些

private void XMLPrase(String path) {
HttpDownloader hd = new HttpDownloader();
String resultStr = hd.download(path);
//输出整个下载到的标签
System.out.println(resultStr);
try{
//创建一个SAXParserFactory
SAXParserFactory factory = SAXParserFactory.newInstance();
XMLReader reader = factory.newSAXParser().getXMLReader();
//为XMLReader设置内容处理器
reader.setContentHandler(new MyContentHandler());
//开始解析文件
reader.parse(new InputSource(new StringReader(resultStr)));
}
catch(Exception e){
e.printStackTrace();
}
}

HttDownloader类封装了download函数,这个函数传入url参数,用于下载网上的xml文件,函数将下载的文件通过stringbuffer在转化为字串,把整个文件放入到一个string字串中,得到了字串文件后,再要解析就OK了。download函数代码还是贴一下吧

public String download(String urlStr) {
StringBuffer sb = new StringBuffer();
String line = null;
BufferedReader buffer = null;
try {
// 创建一个URL对象
url = new URL(urlStr);
// 创建一个Http连接
HttpURLConnection urlConn = (HttpURLConnection) url
.openConnection();
// 使用IO流读取数据
buffer = new BufferedReader(new InputStreamReader(urlConn
.getInputStream()));
while ((line = buffer.readLine()) != null) {
sb.append(line);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
buffer.close();
} catch (Exception e) {
e.printStackTrace();
}
}
return sb.toString();
}


stringbuffer用起来还是挺方便的,转为string非常轻松。那接下来就开始解析了,解析中要用到contenthandler,通过覆盖其中一些函数来解析标签,解析文档,当然咯,大家都知道contenthandler这个接口里面函数很多,直接用这个接口没必要嘛,所以就换种方法,继承他的子类DefaultHandler,然后自己覆盖几个需要用到的函数,这样就简单而且比较清晰了

package dai.xml;

import java.util.ArrayList;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

public class MyContentHandler extends DefaultHandler{
private String tagName=null;
//构建一个放路线上站点的数据类
private RouteData routeData=new RouteData();
//暂时存放线路上的站点的一些信息
private ArrayList<String>stopTag=new ArrayList<String>();
private ArrayList<String>stopTitle=new ArrayList<String>();
private ArrayList<String>stopLat=new ArrayList<String>();
private ArrayList<String>stopLon=new ArrayList<String>();

@Override
public void characters(char[] ch, int start, int length)
throws SAXException {
// TODO Auto-generated method stub
super.characters(ch, start, length);
}

@Override
public void endDocument() throws SAXException {
// TODO Auto-generated method stub
System.out.println("end------------>");
System.out.println(routeData.toString());
super.endDocument();
}

@Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
// 标签解析完毕
if (localName.equals("route")) {
routeData.setStopTag(stopTag);//最后一次添加到对象中去
routeData.setStopTitle(stopTitle);
routeData.setStopLat(stopLat);
routeData.setStopLon(stopLon);
}
//System.out.println("endlelement-------------->");
super.endElement(uri, localName, qName);
}

@Override
public void startDocument() throws SAXException {
// TODO Auto-generated method stub
System.out.println("start------------->");
super.startDocument();
}
//开始解析标签
@Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
// TODO Auto-generated method stub
tagName=localName;
//System.out.println("startelement------>" +localName);
//解析这条路线的基本信息,路线标签,名字,最大的经纬度
if(tagName.equals("route"))
{
//只会发生一次
routeData.setRouteTag(attributes.getValue(0));
routeData.setRouteTitle(attributes.getValue(1));
routeData.setRoutelatMin(attributes.getValue(4));
routeData.setRoutelatMax(attributes.getValue(5));
routeData.setRoutelonMin(attributes.getValue(6));
routeData.setRoutelonMax(attributes.getValue(7));
}
if (localName.equals("stop")) {
//System.out.println("进入stop");
//会有很多次,最后一次再添加的话会更有效率的吧
stopTag.add(attributes.getValue(0));
stopTitle.add(attributes.getValue(1));
stopLat.add(attributes.getValue(2));
stopLon.add(attributes.getValue(3));
}
//System.out.println("startelement------>");
super.startElement(uri, localName, qName, attributes);
}

}

每个函数的作用就不说了,看看字面意思就知道了,解析的大概过程都一样,覆盖的几个函数都是这样,但是往往错误就发生在具体的某个xml文件的标签配对问题上。上次就是在characters函数中把一个标签单词拼错了,搞了一下午都没发现。。郁闷死了,所以啊,还是提醒自己一定要仔细仔细再仔细吧。具体xml文件具体分析吧

这次解析的xml文件是一条公交路线的站点信息,http://webservices.nextbus.com/service/publicXMLFeed?command=routeConfig&a=sf-muni&r=N这里也贴一下把,xml文件就这样,所以characters里面就用不着不写了。。能搞定就行吧。

在数据的存放上,学习了Mars老师的存放数据的方法,不错不错,大家也值得借鉴,话不多说,先贴上~~

package dai.xml;

import java.util.ArrayList;
/*
*
* 此类包含了解析路线xml文件后路线上的站点信息,名称 方位 经纬度等
*
*/
public class RouteData {
private String RouteTag=null;
private String RouteTitle=null;
private String RoutelatMin=null;
private String RoutelatMax=null;
private String RoutelonMin=null;
private String RoutelonMax=null;
private ArrayList<String>stopTag;
public RouteData() {
super();
}
private ArrayList<String>stopTitle;
private ArrayList<String>stopLat;
private ArrayList<String>stopLon;

public String getRouteTag() {
return RouteTag;
}
public void setRouteTag(String routeTag) {
RouteTag = routeTag;
}
public String getRouteTitle() {
return RouteTitle;
}
@Override
public String toString() {
return "RouteData [RouteTag=" + RouteTag + ", RouteTitle=" + RouteTitle
+ ", RoutelatMin=" + RoutelatMin + ", RoutelatMax="
+ RoutelatMax + ", RoutelonMin=" + RoutelonMin
+ ", RoutelonMax=" + RoutelonMax + ", stopTag=" + stopTag
+ ", stopTitle=" + stopTitle + ", stopLat=" + stopLat
+ ", stopLon=" + stopLon + ", stopID=" + stopID + "]";
}
public void setRouteTitle(String routeTitle) {
RouteTitle = routeTitle;
}
public String getRoutelatMin() {
return RoutelatMin;
}
public void setRoutelatMin(String routelatMin) {
RoutelatMin = routelatMin;
}
public String getRoutelatMax() {
return RoutelatMax;
}
public void setRoutelatMax(String routelatMax) {
RoutelatMax = routelatMax;
}
public String getRoutelonMin() {
return RoutelonMin;
}
public void setRoutelonMin(String routelonMin) {
RoutelonMin = routelonMin;
}
public String getRoutelonMax() {
return RoutelonMax;
}
public void setRoutelonMax(String routelonMax) {
RoutelonMax = routelonMax;
}
public ArrayList<String> getStopTag() {
return stopTag;
}
public void setStopTag(ArrayList<String> stopTag) {
this.stopTag = stopTag;
}
public ArrayList<String> getStopTitle() {
return stopTitle;
}
public void setStopTitle(ArrayList<String> stopTitle) {
this.stopTitle = stopTitle;
}
public ArrayList<String> getStopLat() {
return stopLat;
}
public void setStopLat(ArrayList<String> stopLat) {
this.stopLat = stopLat;
}
public ArrayList<String> getStopLon() {
return stopLon;
}
public void setStopLon(ArrayList<String> stopLon) {
this.stopLon = stopLon;
}
public ArrayList<String> getStopID() {
return stopID;
}
public void setStopID(ArrayList<String> stopID) {
this.stopID = stopID;
}
private ArrayList<String>stopID;

}

方法就是新建一个RouteData类,包含了几个数据成员,按照xml文件中的标签来定数据成员的,用来存放解析得到的数据的嘛。类中的几个arraylist存放了tag,title,latitude,lontitude的数据,大小都是一样的,用起来很方便。然后就是搞了一些set,get方法来设定或者得到数据,用eclipse生成下很快的。测试的时候就用个tostring方法,方便快捷。

新建RouteData类的好处就是数据存取就方便了嘛,如果其他地方还要用到数据的话,直接构造一个RouteData对象,在endelement()或者自己觉得能行的地方传递下就行,能轻松把数据传递到当前activity类中,挺好的选择。

最后要说下的就是androidmanifest里面的权限吧,解析的话貌似没什么特别要求,就是要下载的话加上<uses-permission android:name="android.permission.INTERNET"/>咯。OK,就这样。

更多相关文章

  1. C语言的函数递归(下)
  2. Android硬件抽象层(HAL)深入剖析(三)
  3. Android(安卓)NDK 编译过程中遇到错误 exception handling disab
  4. opencv for android 教程(环境搭建篇)
  5. pgsql查看主备节点的方法
  6. 一款常用的 Squid 日志分析工具
  7. GitHub 标星 8K+!一款开源替代 ls 的工具你值得拥有!
  8. RHEL 6 下 DHCP+TFTP+FTP+PXE+Kickstart 实现无人值守安装
  9. Linux 环境下实战 Rsync 备份工具及配置 rsync+inotify 实时同步

随机推荐

  1. Android(安卓)Common Use
  2. Linear Layout
  3. 6
  4. Android系统源代码情景分析:基础知识
  5. 安卓开发 - B站开源的ijkplayer播放器配
  6. Android--利用selector设置Button
  7. AndroidStudio 2.3.3 百度云盘地址
  8. android 2.2 获取联系人,电话,并拨号
  9. cocos2d-x-2.1.4在NDK r9下的编译问题
  10. Android(安卓)获取控件相对于屏幕位置