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

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
	}
	}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值