Pull 解析和 Sax 解析很相似,都是轻量级的解析。在 Android 的内核中已经嵌入了 Pull,所以我们不需要再添加第三方 jar 包来支持 Pull。
Pull 解析和 Sax 解析不一样的地方有:
1)Pull 读取 XML 文件后触发相应的事件调用方法返回的是数字
2)Pull 可以在程序中控制想解析到哪里就可以停止解析
PULL解析器的运行方式和SAX类似,都是基于事件的模式。不同的是,在PULL解析过程中返回的是数字,且我们需要自己获取产生的事件然后做相应的操作,而不像SAX那样由处理器触发一种事件的方法,执行我们的代码。
读取到xml的声明返回 START_DOCUMENT; 读取到xml的结束返回 END_DOCUMENT ; 读取到xml的开始标签返回 START_TAG; 读取到xml的结束标签返回 END_TAG; 读取到xml的文本返回 TEXT |
PULL解析器小巧轻便,解析速度快,简单易用,非常适合在Android移动设备中使用,Android系统内部在解析各种XML时也是用PULL解析器,Android官方推荐开发者们使用Pull解析技术
PULL 的工作原理:XML pull提供了开始元素和结束元素。当某个元素开始时,我们可以调用parser.nextText从XML文档中提取所有字符数据。当解释到一个文档结束时,自动生成EndDocument事件。
这是我们的解析代码
- /**
- * 解析
- * */
- public List<Person> parserXML(InputStream is) {
- // 创建一个list 用来保存解析的xml
- List<Person> persons = null;
- Person person = null;
- XmlPullParser parser = Xml.newPullParser();
- try {
- parser.setInput(is, "utf-8");
- // 获取事件类型
- int event = parser.getEventType();
- while (event != XmlPullParser.END_DOCUMENT) {
- switch (event) {
- case XmlPullParser.START_DOCUMENT:
- // 当前事件是文档开始事件
- // 文档开始时初始化list
- persons = new ArrayList<Person>();
- break;
- case XmlPullParser.START_TAG:
- // 当前事件是标签元素开始事件
- if (parser.getName().equals("person")) {
- // 如果是person标签 则新建person对象 并获取id
- person = new Person();
- person.set_id(parser.getAttributeValue(0));
- } else if (parser.getName().equals("name")) {
- // 判断当前标签是否是name 将值保存到person
- //当某个元素开始时,可以调用 解析器实例的nextText() 从 XML 文档中提取所有字符数据
- person.set_name(parser.nextText());
- } else if (parser.getName().equals("age")) {
- person.set_age(parser.nextText());
- }
- break;
- case XmlPullParser.TEXT:
- break;
- case XmlPullParser.END_TAG:
- // 当前事件是标签元素结束事件
- if (parser.getName().equals("person")) {
- // person标签结束 添加到list并设空person对象
- persons.add(person);
- person = null;
- }
- break;
- default:
- break;
- }
- // 进入下一个元素并触发相应事件
- event = parser.next();
- }
- } catch (Exception e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- return persons;
- }
基本和sax的原理是差不多的 就不去细讲了
接下来讲解怎么通过PULL生成xml
使用到了XmlSerializer类
我们有两种方法去获取XmlSerializer对象
- // 方法1
- XmlSerializer serializer = Xml.newSerializer();
- // 方法2
- XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
- XmlSerializer serializer = factory.newSerializer();
通过serializer的几个方法 来创建xml
首先 设置输出流对象
- serializer.setOutput(writer);
接下来开始写入
- //standalone 用来表示该文件是否呼叫其它外部的文件。
- serializer.startDocument("utf-8", true);
- //start和end成对出现
- serializer.endDocument();
在startDocument和endDocument创建元素,使用startTag和endTag
- //同样的 start和end成对出现
- serializer.startTag(null, "persons");
- serializer.endTag(null, "persons");
如果元素有属性怎么办? 使用下面的方法就添加了属性id
- serializer.attribute(null, "id", person.get_id());
还有 元素需要添加值的时候 该怎么半?
- serializer.text(person.get_name());
到这里 讲的也就差不多了,接下来看下完整的生成方法
- public String createXML() {
- List<Person> persons = getTestValues();
- // 方法1
- XmlSerializer serializer = Xml.newSerializer();
- // 方法2
- // XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
- // XmlSerializer serializer = factory.newSerializer();
- StringWriter writer = new StringWriter();
- try {
- // 设置输出流对象
- serializer.setOutput(writer);
- serializer.startDocument("utf-8", true);
- // 第一个参数为命名空间,如果不使用命名空间,可以设置为null
- serializer.startTag(null, "persons");
- for (int i = 0; i < persons.size(); i++) {
- Person person = persons.get(i);
- serializer.startTag(null, "person");
- serializer.attribute(null, "id", person.get_id());
- serializer.startTag(null, "name");
- serializer.text(person.get_name());
- serializer.endTag(null, "name");
- serializer.startTag(null, "age");
- serializer.text(person.get_age());
- serializer.endTag(null, "age");
- serializer.endTag(null, "person");
- }
- serializer.endTag(null, "persons");
- serializer.endDocument();
- return writer.toString();
- } catch (Exception e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- return null;
- }
我们来调用下这个方法
- Toast.makeText(activity, new Pull().createXML(),
- Toast.LENGTH_LONG).show();
下面就是显示效果 说明生成成功~
Android平台的三个XML生成解析方式已经全部讲完