• Android 下用 Pull 解析和生成 XML


    Java 中是可以用 SAX 和 DOM 解析 XML  的,虽然在 Android 下也可以用这2中方式,但是还是推荐用 Pull。Pull 使用简单,效率相对高,Android 下是集成了 Pull ,所以并不需要用到第三方的包。

    下面来举例子,我要向 XML 文档中读写学生信息,首先我定义一个学生类,包含ID、学号、姓名和年龄

    public class Student {
    	public Student() {};
    	
    	public Student(int id, int number, String name, int age) {
    		this.id = id;
    		this.number = number;
    		this.name = name;
    		this.age = age;
    	}
    
    
    	private int id;
    	private int number;
    	private String name;
    	private int age;
    	
    	public int getId() {
    		return id;
    	}
    	public int getNumber() {
    		return number;
    	}
    	public String getName() {
    		return name;
    	}
    	public int getAge() {
    		return age;
    	}
    	public void setId(int id) {
    		this.id = id;
    	}
    	public void setNumber(int number) {
    		this.number = number;
    	}
    	public void setName(String name) {
    		this.name = name;
    	}
    	public void setAge(int age) {
    		this.age = age;
    	}
    	
    	
    	@Override
    	public String toString() {
    		return "Student [number=" + number + ", name=" + name + ", age=" + age
    				+ "]";
    	}
    }


    要读取的 XML 文件里面内容是这样的

    <?xml version="1.0" encoding="UTF-8"?>
    <students>
    	<student id="1">
    		<number>33</number>
    		<name>张三</name>
    		<age>20</age>
    	</student>
    	<student id="2">
    		<number>29</number>
    		<name>李四</name>
    		<age>19</age>
    	</student>
    </students>

    然后我写了个 XmlHelper 类,有个静态方法 getStudes,该方法接受输入流,返回学生信息的集合

    public static List<Student> getStudents(InputStream xml) throws Exception {
    		List<Student> students = null;
    		Student student = null;
    		XmlPullParser parser = Xml.newPullParser(); //得到 Pull 解析器
    		parser.setInput(xml, "UTF-8");	//设置输入,编码为 UTF-8
    		
    		int event = parser.getEventType(); //得到事件类型,每读取到一个位置都有相对的事件类型
    		while (XmlPullParser.END_DOCUMENT != event) {	//没到文档结尾就要循环读取
    			switch (event) {
    			
    			case XmlPullParser.START_DOCUMENT: //这是文档开始事件,我们在这个地方做一些初始化工作
    				students = new ArrayList<Student>();
    				break;
    				
    			case XmlPullParser.START_TAG:	//标签开始事件,标签开始就是上面XML中的 <students>、<student>、<number>、<name>、和 <age>
    				if (parser.getName().equals("student")) { //读取到这个 student 标签就说明下面就是我需要的信息了
    					int id = Integer.valueOf(parser.getAttributeValue(0));
    					student = new Student();
    					student.setId(id);
    				}
    				if (null != student) { //避免出现空指针,先判断一下再继续
    					if (parser.getName().equals("number")) {
    						int number = Integer.valueOf(parser.nextText()); // nextText() 就是得到标签后面的文本
    						student.setNumber(number);
    					}else if (parser.getName().equals("name")) {
    						String name = parser.nextText();
    						student.setName(name);
    					}else if (parser.getName().equals("age")) {
    						int age = Integer.valueOf(parser.nextText());
    						student.setAge(age);
    					}
    				}
    				break;
    				
    			case XmlPullParser.END_TAG:
    				//读取到 </student> 时说明一个学生的信息已经读取完了
    				if (parser.getName().equals("student")) {
    					students.add(student);
    					student = null;
    				}
    				break;
    				
    			default:
    				break;
    			}
    			event = parser.next(); //一个读取完了,就下一个,如此循环
    		}
    		return students;
    	}


    读取就是这样了,接下来写怎样生成。generate 方法,接受学生信息集合和输出流
    其实成成很好理解,就是按照顺序一块信息一块信息写下去

    public static void generate(List<Student> students, OutputStream os) throws Exception {
    		XmlSerializer serializer = Xml.newSerializer(); //得到序列化器
    		serializer.setOutput(os, "UTF-8"); //设置输出
    		serializer.startDocument("UTF-8", true); //文档开始了
    		serializer.startTag(null, "students"); //标签开始了
    		for (Student student : students) {
    			serializer.startTag(null, "student"); //子标签开始了
    			serializer.attribute(null, "id", String.valueOf(student.getId())); //指定该标签属性,这里是ID
    			
    			//下面3个就是生成学号、姓名和年龄
    			serializer.startTag(null, "number");
    			serializer.text(String.valueOf(student.getNumber()));
    			serializer.endTag(null, "number");
    			
    			serializer.startTag(null, "name");
    			serializer.text(student.getName());
    			serializer.endTag(null, "name");
    			
    			serializer.startTag(null, "age");
    			serializer.text(String.valueOf(student.getAge()));
    			serializer.endTag(null, "age");
    			
    			serializer.endTag(null, "student"); //子标签结束
    		}
    		serializer.endTag(null, "students"); //标签结束
    		serializer.endDocument(); //文档结束
    		os.flush(); //如果传入的输出流不是文件,就就要刷新一下缓冲区
    		os.close();
    	}
    }


    然后咱来写一个测试单元来测试一下这俩方法

    public class XmlHelperTest extends AndroidTestCase {
    	private static final String TAG = "XmlHelperTest";
    	
    	public void testGetStudents() throws Exception {
    		InputStream xmlIstm = this.getClass().getClassLoader().getResourceAsStream("students.xml");
    		List<Student> students = XmlHelper.getStudents(xmlIstm);
    		for (Student student : students) {
    			Log.i(TAG, student.toString());
    		}
    	}
    	
    	public void testGenerate() throws Exception {
    		List<Student> students = new ArrayList<Student>();
    		students.add(new Student(1, 13, "小建", 21));
    		students.add(new Student(2, 16, "大康", 20));
    		
    		File xmlFile = new File(getContext().getFilesDir(), "students.xml");
    		FileOutputStream fos = new FileOutputStream(xmlFile);
    		try {
    			XmlHelper.generate(students, fos);
    			Log.i(TAG, "生成XML文件成功");
    		} catch(Exception e) {
    			Log.i(TAG, "生成XML文件失败:" + e.getMessage());
    		}
    	}
    }


    -----------------------
    楼主以前都是写 C++ 的,也才学 Android 不久,加油吧。
    好久没写博客了,感觉吧,还是应该坚持写下去。

  • 相关阅读:
    《POJ-2369》
    《1402
    《2018 Multi-University Training Contest 8》
    《HDU
    循环串
    模拟赛 数根 题解
    备份
    关于带删除线性基
    论OIer谈恋爱的必要性
    某计数题题解
  • 原文地址:https://www.cnblogs.com/fuhaots2009/p/3455171.html
Copyright © 2020-2023  润新知