public static List<String> parseXmlStr(String xmlStr) { // 设计模式(工厂模式) try { List<String> data = new ArrayList<String>(); // 创建对象有两种方法(只有一种情况可以创建对象) // 1. new 类名(); // 2. 类名.newInstance(); XmlPullParserFactory factory = XmlPullParserFactory.newInstance(); // 从工厂中获取一个parser(专门用来分析xml数据) XmlPullParser parser = factory.newPullParser(); // 把输入的字符串转换成字符输入流Reader Reader in = new StringReader(xmlStr); parser.setInput(in); // 设置parser的输入源(数据的来源) int type = parser.getEventType(); // 分析事件 // 类型包括 // START_DOCUMENT 文档的开始(第一个标签前) (0) // END_DOCUMENT 文档的结束(最后一个标签后) (1) // START_TAG 标签的开始 <city> (2) // END_TAG 标签的结束</city> (3) // TEXT 没有标签的普通文本 beihai (4) boolean flag = false; while(true) { // 一块一块的解析xml字符串 类型可能为上面的内容 // 把开始标签为name和结束标签为name中间的内容找出来 if(type == XmlPullParser.START_DOCUMENT) { // 文档开始 Log.i("XmlPull", "START_DOCUMENT"); } else if(type == XmlPullParser.END_DOCUMENT) { // 文档结束 退出循环 Log.i("XmlPull", "END_DOCUMENT"); break; } else if(type == XmlPullParser.START_TAG) { // 标签开始 String name = parser.getName(); // 获取标签的名称 Log.i("XmlPull", "START_TAG: " + name); if(name.equals("name")) { // 开始标签为<name> 接下来可以获取text了 // 设置boolean类型的变量为true flag = true; } } else if (type == XmlPullParser.END_TAG) { // 标签结束 String name = parser.getName(); // 获取标签的名称 Log.i("XmlPull", "END_TAG: " + name); flag = false; } else if (type== XmlPullParser.TEXT) { // 普通文本 String text = parser.getText(); // 获取文本的内容 Log.i("XmlPull", "TEXT: " + text); if(flag == true) { data.add(text); } } // 移动到下一个块(标签、文本) parser.next(); type = parser.getEventType(); } return data; } catch (XmlPullParserException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return null; }
比较DOM、SAM、PULL?
DOM:
消耗内存:先把xml文档都读到内存中,然后再用DOM JAVASE来访问树形结构,并获取数据。这个写起来很简单,但是很消耗内存。要是数据过大,手机不够牛逼,可能手机直接死机
SAX:
解析效率高,占用内存少,基于事件驱动的:更加简单地说就是对文档进行顺序扫描,当扫描到文档(document)开始与结束、元素(element)开始与结束、文档(document)结束等地方时通知事件处理函数,由事件处理函数做相应动作,然后继续同样的扫描,直至文档结束
PULL:
与SAX类似,也是基于事件驱动,我们可以调用它的next()方法,来获取下一个解析事件(就是开始文档,结束文档,开始标签,结束标签),当处于某个元素时可以调用XmlPullParser的getAttribute()方法来获取属性的值,也可调用用它的nextText()获取本节点的值