1. Pull解析器的运行方式与 SAX 解析器相似。它提供了类似的事件,如:开始元素和结束元素事件,使用parser.next()可以进入下一个元素并触发相应事件。跟SAX不同的是, Pull解析器产生的事件是一个数字,而非方法,因此可以使用一个switch对感兴趣的事件进行处理。当元素开始解析时,调用parser.nextText()方法可以获取下一个Text类型节点的值。
解析如下xml文件:
<?xml version="1.0" encoding="UTF-8" ?> 文档开头 0 <student> 开始标签 2 <name> 开始标签 2 zhangsan 文本标签 4 </name> 结束标签 3 <num> 开始标签 2 10001 文本标签 4 </num> 结束标签 3 <sex> 开始标签 2 male 文本标签 4 </sex> 结束标签 3 </student> 结束标签 3 文档结束 1
XmlSerializer serializer = Xml.newSerializer(); // Xml序列化生成器
XmlPullParser parser = Xml.newPullParser(); // Pull解析器
2. 案例学生管理系统
(1)首先我们看看这个activity_main.xml文件:
1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 2 xmlns:tools="http://schemas.android.com/tools" 3 android:layout_width="match_parent" 4 android:layout_height="match_parent" 5 android:gravity="center_horizontal" 6 android:orientation="vertical" 7 android:paddingLeft="10dip" 8 android:paddingRight="10dip" 9 tools:context=".MainActivity" > 10 11 <TextView 12 android:layout_width="wrap_content" 13 android:layout_height="wrap_content" 14 android:text="学生信息管理系统" 15 android:textColor="#99ff0000" 16 android:textSize="20sp" /> 17 18 <TextView 19 android:layout_width="fill_parent" 20 android:layout_height="wrap_content" 21 android:text="姓名" 22 android:textColor="#9900ff00" 23 android:textSize="14sp" /> 24 25 <EditText 26 android:id="@+id/et_name" 27 android:layout_width="fill_parent" 28 android:layout_height="wrap_content" 29 android:hint="请输入姓名" 30 android:inputType="text" /> 31 32 <TextView 33 android:layout_width="fill_parent" 34 android:layout_height="wrap_content" 35 android:text="学号" 36 android:textColor="#9900ff00" 37 android:textSize="14sp" /> 38 39 <EditText 40 android:id="@+id/et_num" 41 android:layout_width="fill_parent" 42 android:layout_height="wrap_content" 43 android:hint="请输入学号" 44 android:inputType="number" /> 45 46 <TextView 47 android:layout_width="fill_parent" 48 android:layout_height="wrap_content" 49 android:text="性别" 50 android:textColor="#9900ff00" 51 android:textSize="14sp" /> 52 53 <RadioGroup 54 android:id="@+id/rg_sex" 55 android:layout_width="wrap_content" 56 android:layout_height="wrap_content" 57 android:orientation="horizontal" > 58 59 <RadioButton 60 android:id="@+id/rb_male" 61 android:layout_width="wrap_content" 62 android:layout_height="wrap_content" 63 android:checked="true" 64 android:text="男" /> 65 66 <RadioButton 67 android:id="@+id/rb_female" 68 android:layout_width="wrap_content" 69 android:layout_height="wrap_content" 70 android:text="女" /> 71 </RadioGroup> 72 73 <LinearLayout 74 android:layout_width="fill_parent" 75 android:layout_height="fill_parent" 76 android:orientation="vertical" > 77 78 <ScrollView 79 android:layout_width="fill_parent" 80 android:layout_height="0dip" 81 android:layout_weight="1" > 82 83 <LinearLayout 84 android:id="@+id/ll_result" 85 android:layout_width="fill_parent" 86 android:layout_height="0dip" 87 android:layout_weight="1" 88 android:orientation="vertical" > 89 </LinearLayout> 90 </ScrollView> 91 92 <Button 93 android:layout_width="fill_parent" 94 android:layout_height="wrap_content" 95 android:onClick="save" 96 android:text="保存" /> 97 </LinearLayout> 98 99 </LinearLayout>
(2)MainActivity.java:
1 package com.itheima.studentinfo; 2 3 import java.io.File; 4 import java.io.FileInputStream; 5 import java.io.FileOutputStream; 6 import java.io.InputStream; 7 8 import org.xmlpull.v1.XmlPullParser; 9 import org.xmlpull.v1.XmlSerializer; 10 11 import android.app.Activity; 12 import android.os.Bundle; 13 import android.text.TextUtils; 14 import android.util.Xml; 15 import android.view.View; 16 import android.view.Window; 17 import android.widget.EditText; 18 import android.widget.LinearLayout; 19 import android.widget.RadioGroup; 20 import android.widget.TextView; 21 import android.widget.Toast; 22 23 public class MainActivity extends Activity { 24 private EditText et_name; 25 private EditText et_num; 26 private RadioGroup rg_sex; 27 28 //显示结果的页面 29 private LinearLayout ll_result; 30 31 @Override 32 protected void onCreate(Bundle savedInstanceState) { 33 super.onCreate(savedInstanceState); 34 //界面无标题 35 requestWindowFeature(Window.FEATURE_NO_TITLE); 36 setContentView(R.layout.activity_main); 37 et_name = (EditText) findViewById(R.id.et_name); 38 et_num = (EditText) findViewById(R.id.et_num); 39 rg_sex = (RadioGroup) findViewById(R.id.rg_sex); 40 ll_result = (LinearLayout) findViewById(R.id.ll_result); 41 refreshData(); 42 43 } 44 45 //刷新数据 46 private void refreshData() { 47 //清除旧的全部的数据 48 ll_result.removeAllViews(); 49 //解析已经存在的xml文件,把里面的数据全部都获取出来,添加上到界面上 50 File files = getFilesDir(); 51 for(File file :files.listFiles()){ 52 //每个文件都是一个xml 53 //解析xml 54 readXmlInfo(file); 55 } 56 } 57 58 /** 59 * 点击保存学生的信息,生成一个xml文件 60 * @param view 61 */ 62 public void save(View view){ 63 String name = et_name.getText().toString().trim(); 64 String num = et_num.getText().toString().trim(); 65 if(TextUtils.isEmpty(num)||TextUtils.isEmpty(name)){ 66 Toast.makeText(this, "学生姓名或者学号不能为空", 0).show(); 67 return ; 68 } 69 try { 70 File file = new File(getFilesDir(),num+".xml"); 71 FileOutputStream os = new FileOutputStream(file); 72 //采用谷歌api 生成xml文件 73 //1.获取一个xml文件的生成器,序列化器 74 XmlSerializer serializer = Xml.newSerializer(); 75 //2.初始化序列化器 设置写到哪个文件,采用什么样的编码方式 76 serializer.setOutput(os, "utf-8"); 77 //3.开始写数据 ,写xml文件头,文档为独立的xml文件 78 serializer.startDocument("utf-8", true); 79 serializer.startTag(null, "student"); 80 serializer.startTag(null, "name"); 81 serializer.text(name); 82 serializer.endTag(null, "name"); 83 serializer.startTag(null, "num"); 84 serializer.text(num); 85 serializer.endTag(null, "num"); 86 serializer.startTag(null, "sex"); 87 if(rg_sex.getCheckedRadioButtonId()==R.id.rb_male){ 88 serializer.text("male"); 89 }else{ 90 serializer.text("female"); 91 } 92 serializer.endTag(null, "sex"); 93 serializer.endTag(null, "student"); 94 serializer.endDocument(); 95 os.close(); 96 Toast.makeText(this, "保存数据成功", 0).show(); 97 refreshData(); 98 } catch (Exception e) { 99 e.printStackTrace(); 100 Toast.makeText(this, "保存数据失败", 0).show(); 101 } 102 } 103 104 private void readXmlInfo(File file){ 105 try { 106 //1.初始化解析器 107 XmlPullParser parser = Xml.newPullParser(); 108 //2.设置解析器的参数 109 InputStream inputStream = new FileInputStream(file); 110 parser.setInput(inputStream, "utf-8"); 111 int type = parser.getEventType(); 112 StringBuilder sb = new StringBuilder(); 113 while(type!=XmlPullParser.END_DOCUMENT){ 114 switch (type) { 115 case XmlPullParser.START_TAG: 116 if("name".equals(parser.getName())){ 117 //这是name节点 118 String name = parser.nextText(); 119 sb.append("--name:"+name); 120 }else if("num".equals(parser.getName())){ 121 //这是name节点 122 String num = parser.nextText(); 123 sb.append("--num:"+num); 124 }else if("sex".equals(parser.getName())){ 125 //这是name节点 126 String sex = parser.nextText(); 127 sb.append("--sex:"+sex); 128 } 129 break; 130 } 131 type = parser.next();//让解析器解析下一个元素 132 } 133 inputStream.close(); 134 String text = sb.toString(); 135 TextView tv = new TextView(this); 136 tv.setText(text); 137 ll_result.addView(tv); 138 } catch (Exception e) { 139 e.printStackTrace(); 140 TextView tv = new TextView(this); 141 tv.setText("这条数据无效"); 142 ll_result.addView(tv); 143 } 144 } 145 146 147 }
pull解析xml文件的步骤:
1. 初始化一个xml的Pull解析器
XmlPullParser parser = Xml.newPullParser();
2. 设置解析器的参数
InputStream inputStream = this.getAssets().open("10001.xml");//这里使用资产文件举例说明而已
parser.setInput(inputStream, "utf-8");
3. 读数据
效果图如下:
这是在真机上面运行的,这些xml数据保存在:
我们随便打开一个100017.xml文件如下:
注意:(1)刷新数据,代码如下:
private void refreshData(){
//清除旧的全部的数据
ll_result.removeAllViews(); //必须先删除之前所有数据,不然的会出现数据大量重复出现
//解析已经存在的xml文件,把里面的数据全部都获取出来,添加上到界面上
File files = getFilesDir();
for(File file :files.listFiles()){//每个文件都是一个xml
//解析xml
readXmlInfo(file);
}
}
(2)动态设置LinearLayout的布局元素:
ll_result = (LinearLayout) findViewById(R.id.ll_result);
……
TextView tv = new TextView(this);
tv.setText(text);
ll_result.addView(tv);//动态添加TextView