android中SAX解析(XML)

1、sax解析比pull解析要通用一点,不用写那么多的POJO。一般字段比较少的话用pull解析。

2、sax解析需要继承DefaultHandler这个类。

3、解析的相关代码:

package com.mqp.sax_customer;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

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

/**
 * 解析xml文件,然后通过list集合返回
 * 
 * @author Administrator
 * 
 */

public class MyHandle extends DefaultHandler {

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

	// 通过传入的节点开始解析
	public MyHandle(String nodeName) {
		this.nodeName = nodeName;
	}

	// 通过list的get方法得到对象集
	public List<HashMap<String, String>> getList() {
		return list;
	}

	@Override
	public void startDocument() throws SAXException {
		// 当遇到第一个标签的时候
	}

	// 开始元素
	@Override
	public void startElement(String uri, String localName, String qName,
			Attributes attributes) throws SAXException {
		// 当遇到文档的时候(我们传进来的nodeName等于解析到的qName的时候)
		if (qName.equals(nodeName)) {
			map = new HashMap<String, String>();
		}
		// 判断节点是否有属性值(比如id),有的话读出来放在map里面
		if (attributes != null) {
			for (int i = 0; i < attributes.getLength(); i++) {
				map.put(attributes.getQName(i), attributes.getValue(i));
				// 属性指的是节点里边的属性比如ID
			}
		}
		currentTag = qName;
	}

	// 开始元素里边的子节点
	@Override
	public void characters(char[] ch, int start, int length)
			throws SAXException {
		// 开始解析文本节点,比如name,age(文本节点值得是父节点下边有子节点)
		if (currentTag != null && map != null) {
			currentValue = new String(ch, start, length);
		}
		if (currentValue != null && !currentValue.trim().equals("")
				&& !currentValue.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;// 让map等于空
		}
	}

	@Override
	public void endDocument() throws SAXException {

	}
}


4、创建解析工厂类,调用MyHandle解析类。返回的是List,放在自己写的一个类中...

package com.mqp.sax_customer;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.SAXException;

/**
 * 创建解析工厂类
 * 
 * @author Administrator
 * 
 */

public class SaxParse {

	public static List<HashMap<String, String>> parseXML(InputStream in,
			String nodeName) {
		// 创建解析工厂
		SAXParserFactory factory = SAXParserFactory.newInstance();
		// 通过工厂创建解析器
		try {
			SAXParser sax = factory.newSAXParser();
			// 实例化解析类,传入开始解析的节点
			MyHandle handle = new MyHandle(nodeName);
			sax.parse(in, handle);// 自动掉用MyHandle进行解析,然后返回我们想要的List集合-------------------

			// 通过SaxParseXML中的getList方法得到list集合
			in.close();// 记得关上流文件
			return handle.getList();
		} catch (ParserConfigurationException e) {
			e.printStackTrace();
		} catch (SAXException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}

	public static List<HashMap<String, String>> getList() {
		String path = "http://yx669.com/androidweb/SelectData.asp";
		String sql = "select * from [Customer]";
		Map<String, String> maps = new HashMap<String, String>();
		maps.put("SQL", sql);

		InputStream in = Android_Form.getXML(path, maps);// 解析的时候得先获得流文件-----,从服务器端取得流文件
		if (in != null) {
			List<HashMap<String, String>> list = SaxParse
					.parseXML(in, "person");
			return list;
		} else {
			List<HashMap<String, String>> lilith = new ArrayList<HashMap<String, String>>();
			HashMap<String, String> map = new HashMap<String, String>();
			map.put("CName", "您没有查询到任何东西!!!!");
			lilith.add(map);
			return lilith;
		}

	}

}



5、解析是完成了,可是我们怎么去服务器取得xml文件呢,大家都知道数据的传输我们都是通过流来传输的,下面就从服务器获得流文件。

代码如下(也就是android中的form提交数据,相对安全):

package com.mqp.sax_customer;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.Map;

public class Android_Form {

	private static InputStream inputStream = null;

	// 返回流,要获得xml先传入路径过去
	public static InputStream getXML(String path, Map<String, String> maps) {
		InputStream inputStream = null;
		String encode = "utf-8";
		try {
			URL url = new URL(path);
			HttpURLConnection conn = (HttpURLConnection) url.openConnection();
			conn.setReadTimeout(10 * 1000);
			conn.setRequestMethod("POST");
			conn.setDoOutput(true);
			conn.setDoInput(true);
			conn.setUseCaches(false);// post方式不能使用缓存
			conn.setRequestProperty("Connection", "Keep-Alive");// 维持长连接

			StringBuffer sb = new StringBuffer();
			for (Map.Entry<String, String> map : maps.entrySet()) {
				sb.append(map.getKey()).append("=")
						.append(URLEncoder.encode(map.getValue(), encode))
						.append('&');
			}
			String info = sb.substring(0, sb.length() - 1);
			byte[] b = info.getBytes();
			conn.setRequestProperty("Content-Type",
					"application/x-www-form-urlencoded");
			conn.setRequestProperty("Content-Length", String.valueOf(b.length));// 两个属性是必须的

			OutputStream out = conn.getOutputStream();
			out.write(b); // 以流的方式将条件写入到服务器方
			out.flush(); // 把内存中的数据刷新输送给对方
			out.close(); // 关闭流

			int code = conn.getResponseCode();// 获得响应码
			if (code == 200) {
				inputStream = conn.getInputStream();
				return inputStream;
			}

		} catch (MalformedURLException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return inputStream;
	}
}


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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值