Pull解析
(一)概述
1、Pull解析器是一个开源的Java项目,Android系统内部解析xml文件均为此种方式。Pull是轻量级的解析。在Android 的内核中已经内嵌了Pull,所以不需要再添加第三方jar包来支持Pull。
2、Pull读取XML文件时采用事件触发机制,事件这里是指文档开始、标签开始、标签结束、文档结束等。Pull将事件用整型数据表示,不同的事件用不同的整数表示,如此极大地简化了解析代码的书写。
3、Pull以流的方式解析XML文档,Pull解析可以在程序中控制想解析到哪里就可以停止解析。
4、Android系统默认使用Pull解析XML文档。
(二)相关类/接口
1、XmlPullFactory类:解析器工厂类,用于创建解析器对象。
2、XmlPullParser类:解析器类,用于解析XML文档。
(三)XmlPullFactory类的常用方法
public static XmlPullFactory newInstance()
作用:返回一个XmlPullFactory对象。
(四)XmlPullParser类的常用方法
1.public void setInput(InputStream inputStream,String inputEncoding) 作用:设置需要解析的输入流对象。 参数——inputStream:输入流对象 参数——inputEncoding:xml文档的编码格式 2.public int getEventType() 作用:返回当前事件的类型值,常用事件类型值。 说明: 1)XmlPullParser.START_DOCUMENT:文档开始 2)XmlPullParser.END_DOCUMENT:文档结束 3)XmlPullParser.START_TAG:标签开始 4)XmlPullParser.END_TAG:标签结束 3.public int next() 作用:获取下一个解析器事件 4.public String getName() 作用:返回当前元素名即标签名称 5.public String getAttributeValue(int index) 作用:返回指定索引值的属性值
(五)使用步骤
步骤1、创建解析器工厂对象,示例代码: factory = XmlPullParserFactory.newInstance(); 步骤2、创建解析器对象,示例代码: XmlPullParser parser = factory.newPullParser(); 步骤3、获取输入流对象,示例代码: InputStream in = new FileInputStream("d:/se2/day12/user.xml"); 步骤4、设置解析器操作的输入流对象并设置编码格式,示例代码: parser.setInput(in,"urf-8"); 步骤5、以下循环一次读取XML文档中的每个节点,示例代码: for(int type = parser.getEventType(); //获取解析的事件 type != XmlPullParser.END_DOCUMENT;// 不是文档结束事件 type = parser.next()){ // 获取下一个事件 // 在循环中编写获取每个XML节点的代码,例如: String tagName = parser.getName();// 获取当前节点的名称 ... }
实际案例:
package com.jxust.elts.dao; import java.io.IOException; import java.io.InputStream; import java.lang.reflect.Array; import java.util.ArrayList; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserFactory; import com.jxust.elts.entity.ExamInfo; import com.jxust.elts.entity.Files; import com.jxust.elts.entity.Question; import com.jxust.elts.entity.User; import com.jxust.elts.utils.HttpUtils; import com.jxust.elts.utils.HttpUtils.RequestMethod; import android.R.array; import android.content.Context; import android.util.Xml; public class ExamBao_PullParse extends ExamDaoBase implements IExamDao { Files mFiles; public ExamBao_PullParse(Context context) { mFiles = getFiles(context); // 获取当前下载的文件的url } @Override public ArrayList<Question> loadQuestions() { // ===========采用Pull解析=============== ArrayList<Question> questions = new ArrayList<Question>(); String url = mFiles.getUrl() + mFiles.getFnQuestion(); // 获取完整路径 InputStream in = null; try { in = HttpUtils.getInputStream(url, null, RequestMethod.GET); XmlPullParser parser = XmlPullParserFactory.newInstance().newPullParser(); parser.setInput(in,"utf-8"); for(int evenType = XmlPullParser.START_DOCUMENT; // 初始条件是要从开始文档事件开始 evenType != XmlPullParser.END_DOCUMENT; // 结束循环是判断是否到达了结束文档事件 evenType = parser.next()){ // 每次执行后都会跳到下一个事件 if(evenType == XmlPullParser.START_TAG){ // 标签开始 String tagName = parser.getName(); if("question".equals(tagName)){ String answer = parser.getAttributeValue(null, "answer"); // 第一个表示名字空间,第二个表示属性值 ArrayList<String> answers = new ArrayList<String>(); for(int i = 0;i < answer.length();i++){ answers.add(answer.charAt(i)+""); } int score = Integer.parseInt(parser.getAttributeValue(null,"score")); int level = Integer.parseInt(parser.getAttributeValue(null, "level")); String title = parser.getAttributeValue(null,"title"); StringBuilder options = new StringBuilder(); for(int i = 4;i <= 7;i++){ options.append(parser.getAttributeValue(i)).append("\n"); } Question q = new Question(answers, level, score, title, options.toString()); questions.add(q); } } } return questions; } catch (Exception e) { e.printStackTrace(); }finally { if(in != null){ try { in.close(); // 关闭输入流资源 } catch (IOException e) { e.printStackTrace(); } } HttpUtils.closeClient(); // 关闭服务器服务 } return null; } @Override public ExamInfo loadExamInfo() { // ===========采用Pull解析=============== String url = mFiles.getUrl() + mFiles.getFnExamInfo(); // 这个就是完整的地址 InputStream in = null; try { in = HttpUtils.getInputStream(url, null, HttpUtils.RequestMethod.GET); XmlPullParserFactory factory = XmlPullParserFactory.newInstance(); XmlPullParser parser = factory.newPullParser(); // 创建用于Pull解析的解析器 parser.setInput(in,"utf-8"); // 设置需要解析的输入流对象,参数1:输入流对象,参数2:输入流对象编码方式 ExamInfo examInfo = new ExamInfo(); for(int eventType = XmlPullParser.START_DOCUMENT; // 循环开始是开始文档 eventType != XmlPullParser.END_DOCUMENT; // 循环结束是文档结束 eventType = parser.next()){ // 操作完一次以后就跳到下一个事件 if(eventType == XmlPullParser.START_TAG){ // 如果是标签开始 String tagName = parser.getName(); // 获取标签名称 if("exam info".equals(tagName)){ examInfo.setSubjectTitle(parser.getAttributeValue(0)); // 拿到考试名称 examInfo.setLimitTime(Integer.parseInt(parser.getAttributeValue(1))); // 拿到考试时间 examInfo.setQuestionCount(Integer.parseInt(parser.getAttributeValue(2))); // 拿到考题数量 return examInfo; // 就只有一个所以直接返回 } } } } catch (Exception e) { e.printStackTrace(); }finally { if(in != null){ try { in.close(); // 关闭输入流 } catch (IOException e) { e.printStackTrace(); } } HttpUtils.closeClient(); // 把服务器的连接也关掉 } return null; } @Override protected void loadUsers() { String url = mFiles.getUrl() + mFiles.getFnUser(); // 获取完整的Url地址 InputStream in = null; try { in = HttpUtils.getInputStream(url, null, HttpUtils.RequestMethod.GET); XmlPullParser parser = XmlPullParserFactory.newInstance().newPullParser(); parser.setInput(in,"utf-8"); for(int evenType = XmlPullParser.START_DOCUMENT; evenType != XmlPullParser.END_DOCUMENT; evenType = parser.next()){ if(evenType == XmlPullParser.START_TAG){ String tagName = parser.getName(); if("user".equals(tagName)){ int id = Integer.parseInt(parser.getAttributeValue(null, "id")); String name = parser.getAttributeValue(null, "name"); String password = parser.getAttributeValue(null,"passsword"); String phone = parser.getAttributeValue(null, "phone"); String email = parser.getAttributeValue(null, "email"); User user = new User(id, name, password, phone, email); mUsers.put(user.getId(), user); // 将user存到本地 } } } } catch (Exception e) { e.printStackTrace(); }finally { if(in != null){ try { in.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } HttpUtils.closeClient(); } } }
<?xml version="1.0" encoding="utf-8"?> <resources> <string name="examInfo"> 考试科目:core java 考生编号:1001\n 考试时间:10分钟 考题数量:20</string> <string name="question">1.能直接由计算机硬件识别的是______。\n A.高级语言\n B.中级语言\n C.汇编语言\n D.机器语言 </string> <string name="app_name">在线考试</string> <string name="action_settings">Settings</string> <string name="hello_world">Hello world!</string> <string name="root_url">http://10.0.2.2/</string> <string name="user_txt">elts-txt/users.txt</string> <string name="exam_info_txt">elts-txt/exam_info.txt</string> <string name="question_txt">elts-txt/questions.txt</string> <string name="user_xml">elts-xml/users.xml</string> <string name="exam_info_xml">elts-xml/exam_info.xml</string> <string name="question_xml">elts-xml/questions.xml</string> <string name="user_json">elts-json/users.json</string> <string name="exam_info_json">elts-json/exam_info.json</string> <string name="question_json">elts-json/questions.json</string> <!-- parse_mode代表解析文件的类型,有四种可选值: txt:文本文件 pull_xml:xml文件 sax_xml:sax解析,使用的xml文件与pull_xml相同 json:json文件 --> <string name="parse_mode">pull_xml</string> <string name="title_activity_login">登录窗口</string> <string name="title_activity_exam">考试窗口</string> <string name="title_activity_main_menu">考试主窗口</string> </resources>