您的位置:首页 > 其它

安卓解析XML文件系列1:使用SAX方式

2015-10-07 21:39 495 查看
HTTP数据组织方式:

HTML方式、XML方式、JSON方式

XML称为可扩展标记语言,它与HTML一样,都是SGML(标准通用标记语言)。

Android中,解析XML数据的三种方式:

1.DOM(org.w3c.dom)

"文档对象模型"方式,解析完的XML将生成一个树状结构的对象。

2.SAX(org.xml.sax)

SimpleAPI for XML,以事件的形式通知程序,对XML进行解析。

3.XMLPULL(org.xmlpull.v1)

类似于SAX方式,程序以“拉取”得方式对XML进行解析。

SAX是一种以事件驱动的XMLapi,由它定义的事件流可以指定从解析器传到专门的处理程序的代码的XML结构,简单的讲,它解析速度快,占用内存少的解析器。这种解析器比较适合android等移动设备。

使用SAX的优点是:

因为SAX的优势是流的方式处理,当遇到一个标签的时候,并不会记录下当前所碰到的标签。

也就是说,startEelment方法中,你所知道的信息,仅仅是当前的签名的名字和属性,至于标签的嵌套结构,上层标签的名字,是否有子元素与其他结构相关的信息,都是不知道的。

使用SAX方式解析XML文件是我们经常使用的方式之一,下面我们来分享一下它的使用方法。

这个例子实现的是使用SAX方式解析XML文件,将web上的一个xml文件解析出语义。

整体思路:新建一个java工程,定义一个MyHandler类,继承DefaultHandler类,在里面定义一个HashMap对象,存储单个解析的完整对象,定义一个List对象,存储所有的解析对象,定义三个字符串对象,分别表示正在解析的元素标签currentTag、解析当前元素的值currentValue、解析当前的节点名称nodeName,在构造方法中给节点名称赋值,写一个getList方法,返回List对象,重写这个类里面的方法,startDocument方法当读到第一个开始标签的时候会触发,在这个方法中创建一个List对象,startElement方法当解析到开始元素的时候会触发,在这个方法中如果是解析的当前节点,则创建一个Map对象,如果Map对象不等于空的话,把解析的值放入Map对象中,把qName赋值给currentTag,characters方法当读取文档节点内容的时候会触发,在这个方法中如果正在解析的元素标签不等于空并且Map对象不等于空的话,把解析的字符串赋值给currentValue,如果currentValue不等于空或者换行符的话,把currentTag和currentValue放到Map对象中,并把currentTag和currentValue置空,endElement方法当遇到结束标志的时候会触发,在这个方法中如果nodeName等于qName的话,把Map对象加到List对象中,Map对象置空;定义一个HttpUtils类,在里面定义一个getXML方法,使用网址创建HttpURLConnection对象,设置它的超时时间、请求方式、获取服务器返回码,如果请求完成的话,返回请求结果的内容。定义一个SaxService类,在里面定义一个readXML方法,创建一个解析XML的工厂对象,解析XML,定义一个解析当前节点的MyHandler对象,返回对象中的内容。定义一个Test类,定义一个字符串类型变量path,用网络上解析的xml的网址对其赋值,对person节点进行解析,把解析的内容遍历输出。

MyHandler.java文件:

public class MyHandler extends DefaultHandler {

private HashMap<String, String> map=null;//存储单个解析的完整对象
private List<HashMap<String, String>> list=null;//存储所有的解析对象
private String currentTag=null;//正在解析的元素标签
private String currentValue=null;//解析当前元素的值
private String nodeName=null;//解析当前的节点名称

public MyHandler(String nodeName) {
// TODO Auto-generated constructor stub
this.nodeName=nodeName;
}

public List<HashMap<String, String>> getList() {
return list;
}

//重写这个类里面的方法

//	解析到开始文档的时候会触发的事件
@Override
public void startDocument() throws SAXException {
// TODO Auto-generated method stub
//		当读到第一个开始标签的时候,会触发这个方法
list=new ArrayList<HashMap<String, String>>();
}

//	解析到开始元素的时候会触发的事件
@Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
// TODO Auto-generated method stub
//    	当遇到文档的开头的时候,调用这个方法
if(qName.equals(nodeName)){
map=new HashMap<String,String>();
}
if(attributes!=null&&map!=null){
for(int i=0;i<attributes.getLength();i++){
map.put(attributes.getQName(i), attributes.getValue(i));
}
}
currentTag=qName;
}

//  读取文档节点内容的时候会触发的事件
@Override
public void characters(char[] ch, int start, int length)
throws SAXException {
//    	这个方法是用来处理xml文件所读取到的内容
if(currentTag!=null&&map!=null){
currentValue=new String(ch,start,length);
if(currentValue!=null&&!currentValue.trim().equals("")&&!currentValue.trim().equals("\n")){
map.put(currentTag, currentValue);
}
}
currentTag=null;//把当前节点对应的值和标签设置为空
currentValue=null;
}

//  当我们把整个文档解析完成的时候触发的事件
@Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
//    	遇到结束标志的时候会调用这个方法
if(qName.equals(nodeName)){
list.add(map);
map=null;
}
super.endElement(uri, localName, qName);
}
}


HttpUtils.java文件:

public class HttpUtils {

public HttpUtils() {
// TODO Auto-generated constructor stub
}

public static InputStream getXML(String path){
InputStream inputStream=null;
try {
URL url=new URL(path);
if(url!=null){
HttpURLConnection connection=(HttpURLConnection)url.openConnection();
connection.setConnectTimeout(3000);
connection.setDoInput(true);
connection.setRequestMethod("GET");
int code=connection.getResponseCode();
if(code==200){
inputStream=connection.getInputStream();
}
}
} catch (Exception e) {
// TODO: handle exception
}
return inputStream;
}

}

SaxService.java文件:

public class SaxService {

public SaxService() {
// TODO Auto-generated constructor stub
}

public static List<HashMap<String, String>> readXML(InputStream inputStream,String nodeName){

try {
//创建一个解析XML的工厂对象
SAXParserFactory spf=SAXParserFactory.newInstance();
SAXParser parser=spf.newSAXParser();//解析XML
MyHandler handler=new MyHandler(nodeName);
parser.parse(inputStream, handler);
inputStream.close();
return handler.getList();
} catch (Exception e) {
// TODO: handle exception
}

return null;
}

}
Test.java文件:

public static void main(String[] args) {
// TODO Auto-generated method stub
String path="http://172.21.75.194:8080/myhttp/person.xml";
//       从服务器端将xml文件取回之后以流的形式返回
InputStream inputStream=HttpUtils.getXML(path);
try {
List<HashMap<String, String>> list=SaxService.readXML(inputStream, "person");
for(HashMap<String, String> map:list){//使用增强for循环
System.out.println(map.toString());
}
} catch (Exception e) {
// TODO: handle exception
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: