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()获取本节点的值