Android中级之网络数据解析一之xml解析


本文来自http://blog.****.net/liuxian13183/ ,引用必须注明出处!

--Comic Sans MS



Xml解析具有跨平台性,语言无关性,易操作性,因此广受开发者的欢迎。作为安卓开发者,至少有三种解析方式需要理解,Dom、Sax、Pull。

另外Java的四种解析XML的方法:http://developer.51cto.com/art/200903/117512.htm

1、首先讲一下dom解析

解析原理:将xml装入Dom树,依次根据Tag查到每个节点,然后取得结点里的对象属性。

以本地xml解析为例:

book.xml放到项目lib目录下

<?xml version="1.0" encoding="UTF-8"?>
<books>
	<book id="12">
		<name>thinking in java</name>
		<price>85.5</price>
	</book>
	<book id="15">
		<name>Spring in Action</name>
		<price>39.0</price>
	</book>
</books>

操作逻辑:

public static void main(String[] args) throws Exception {
		InputStream input = new FileInputStream("lib/book.xml");
		List<Book> books = getBooks(input);
		for (Book book : books) {
			System.out.println(book.toString());
		}
	}

	public static List<Book> getBooks(InputStream inputStream) throws Exception {
		List<Book> list = new ArrayList<Book>();
		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();//new一个factory来处理文件
		DocumentBuilder builder = factory.newDocumentBuilder();//做一个处理框架
		Document document = builder.parse(inputStream);// 把文件形成流的形式,放到一个doucument对象里
		Element element = document.getDocumentElement();// 获得其中的元素集
		NodeList bookNodes = element.getElementsByTagName("book");// 获得元素集下有一叫book的集合
		for (int i = 0; i < bookNodes.getLength(); i++) {
			Element bookElement = (Element) bookNodes.item(i);// 获取一个元素,然后设值
			Book book = new Book();
			book.setId(Integer.valueOf(bookElement.getAttribute("id")));
			NodeList childNodes = bookElement.getChildNodes();

			for (int j = 0; j < childNodes.getLength(); j++) {
				if (childNodes.item(j).getNodeType() == Node.ELEMENT_NODE) {// 结点
					String type=childNodes.item(j).getNodeName();
					String value = childNodes.item(j).getFirstChild()
							.getNodeValue();
					if ("name".equals(type)) {
						book.setName(value);
					} else if ("price".equals(type)) {
						book.setPrice(Float.valueOf(value));
					}
				}
			}// end for j
			list.add(book);
		}// end for i
		return list;
	}

2、

其次sax解析也相当常用

解析原理:将xml装入Sax解析工厂中,根据既定的模式可选择解析,使用的是标记事件驱动方式。

BookXmlHandler:

public class BookXMLHandler extends DefaultHandler {

	private List<Book> books;
	private Book book;
	private String tag;

	public List<Book> getBooks() {
		// TODO Auto-generated method stub
		return books;
	}

	/*
	 * 文档开始时触发
	 */
	@Override
	public void startDocument() throws SAXException {
		super.startDocument();
		books = new ArrayList<Book>();
	}

	/*
	 * 元素开始时触发
	 */
	@Override
	public void startElement(String uri, String localName, String qName,
			Attributes attributes) throws SAXException {
		super.startElement(uri, localName, qName, attributes);
		tag = qName;
		if ("book".equals(tag)) {
			book = new Book();
			book.setId(Integer.valueOf(attributes.getValue(0)));
		}
	}

	/*
	 * 读取元素内容
	 */
	@Override
	public void characters(char[] ch, int start, int length)
			throws SAXException {
		super.characters(ch, start, length);
		if (tag == null) {
			return;
		}
		String content = new String(ch, start, length);
		if (content.trim().equalsIgnoreCase(null)
				|| content.trim().equalsIgnoreCase("")) {
			return;
		}// 一定要记得trim
		if ("name".equals(tag)) {
			book.setName(content);
		} else if ("price".equals(tag)) {
			System.out.println(content);
			book.setPrice(Float.valueOf(content));
		}
	}

	/*
	 * 元素结束时触发
	 */
	@Override
	public void endElement(String uri, String localName, String qName)
			throws SAXException {
		super.endElement(uri, localName, qName);
		if ("book".equals(qName)) {
			books.add(book);
			book = null;
			tag = null;
		}
	}

	/*
	 * 文档结束时触发
	 */
	@Override
	public void endDocument() throws SAXException {
		super.endDocument();
	}
}

操作逻辑:

	public static void main(String[] args) throws Exception {
		// TODO Auto-generated method stub
		InputStream input = new FileInputStream("lib/book.xml");
		List<Book> books = getBooks(input);
		for (Book book : books) {
			System.out.println(book.toString());
		}
	}

	private static List<Book> getBooks(InputStream input) throws Exception {
		// TODO Auto-generated method stub
		SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
		SAXParser saxParser = saxParserFactory.newSAXParser();
		BookXMLHandler handler = new BookXMLHandler();
		saxParser.parse(input, handler);
		return handler.getBooks();
	}

3、

第三种pull解析在安卓中是个特例

解析原理:它比Sax封装又高一个等级,是Sax的浓缩版,测试需要在Android环境下测。

测试逻辑:

public class PullParseTest extends AndroidTestCase {
	public void testPull() throws Exception {
		InputStream input = getContext().getAssets().open("book.xml");
		List<Book> books = getBooks(input);
		for (Book book : books) {
			Log.i("AthrunTag", book.toString());
		}
	}

	public List<Book> getBooks(InputStream inputStream) throws Exception {
		List<Book> books = null;
		Book book = null;
		XmlPullParser parser = Xml.newPullParser();
		parser.setInput(inputStream, "UTF-8");
		int event = parser.getEventType();// 产生第一个事件
		while (event != XmlPullParser.END_DOCUMENT) {
			switch (event) {
			case XmlPullParser.START_DOCUMENT:// 判断当前事件是否是文档开始事件
				books = new ArrayList<Book>();// 初始化books集合
				break;
			case XmlPullParser.START_TAG:// 判断当前事件是否是标签元素开始事件
				if ("book".equals(parser.getName())) {// 判断开始标签元素是否是book
					book = new Book();
					book.setId(Integer.parseInt(parser.getAttributeValue(0)));// 得到book标签的属性值,并设置book的id
				}
				if (book != null) {
					if ("name".equals(parser.getName())) {// 判断开始标签元素是否是name
						book.setName(parser.nextText());
					} else if ("price".equals(parser.getName())) {// 判断开始标签元素是否是price
						book.setPrice(Float.parseFloat(parser.nextText()));
					}
				}
				break;
			case XmlPullParser.END_TAG:// 判断当前事件是否是标签元素结束事件
				if ("book".equals(parser.getName())) {// 判断结束标签元素是否是book
					books.add(book);// 将book添加到books集合
					book = null;
				}
				break;
			}
			event = parser.next();// 进入下一个元素并触发相应事件
		}// end while
		return books;
	}
}

三种解析“真相”只有一个!

12:thinking in java:85.5
15:Spring in Action:39.0

3Q!


上一篇:Java高级之数据格式化


下一篇:Java技术_每天掌握一种设计模式(002)_使用场景及简单实例(创建型:单例模式)