本文来自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!