Android(java)学习笔记128:xml文件生成
1.xml文件:
用元素描述数据,跨平台。
2.利用传统的方式创建xml文件,下面是一个案例:
设计思路:建立一个学生管理系统,创建xml文件保存学生信息;
(1)首先是布局文件activity_main.xml文件,如下:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center_horizontal" android:orientation="vertical" android:paddingLeft="10dip" android:paddingRight="10dip" tools:context=".MainActivity" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="学生信息管理系统" android:textColor="#99ff0000" android:textSize="20sp" /> <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="姓名" android:textColor="#9900ff00" android:textSize="14sp" /> <EditText android:id="@+id/et_name" android:layout_width="fill_parent" android:layout_height="wrap_content" android:hint="请输入姓名" android:inputType="text" /> <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="学号" android:textColor="#9900ff00" android:textSize="14sp" /> <EditText android:id="@+id/et_num" android:layout_width="fill_parent" android:layout_height="wrap_content" android:hint="请输入学号" android:inputType="number" /> <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="性别" android:textColor="#9900ff00" android:textSize="14sp" /> <RadioGroup android:id="@+id/rg_sex" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal" > <RadioButton android:id="@+id/rb_male" android:layout_width="wrap_content" android:layout_height="wrap_content" android:checked="true" android:text="男" /> <RadioButton android:id="@+id/rb_female" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="女" /> </RadioGroup> <RelativeLayout android:layout_width="fill_parent" android:layout_height="fill_parent" > <Button android:onClick="save" android:layout_alignParentBottom="true" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="保存" /> </RelativeLayout> </LinearLayout>
效果图:
(2)逻辑核心代码如下:MainActivity.java:
package com.itheima.studentinfo; import java.io.File; import java.io.FileOutputStream; import android.app.Activity; import android.os.Bundle; import android.text.TextUtils; import android.view.View; import android.view.Window; import android.widget.EditText; import android.widget.RadioGroup; import android.widget.Toast; public class MainActivity extends Activity { private EditText et_name; private EditText et_num; private RadioGroup rg_sex; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //界面无标题 requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.activity_main); et_name = (EditText) findViewById(R.id.et_name); et_num = (EditText) findViewById(R.id.et_num); rg_sex = (RadioGroup) findViewById(R.id.rg_sex); } /** * 点击保存学生的信息,生成一个xml文件 * @param view */ public void save(View view){ String name = et_name.getText().toString().trim(); String num = et_num.getText().toString().trim(); if(TextUtils.isEmpty(num)||TextUtils.isEmpty(name)){ Toast.makeText(this, "学生姓名或者学号不能为空", 0).show(); return ; } try { File file = new File(getFilesDir(),num+".xml"); FileOutputStream fos = new FileOutputStream(file); StringBuilder sb = new StringBuilder();
//传统地建立xml文件 sb.append("<?xml version=\"1.0\" encoding=\"utf-8\"?>"); sb.append("<student>"); sb.append("<name>"); sb.append(name); sb.append("</name>"); sb.append("<num>"); sb.append(num); sb.append("</num>"); sb.append("<sex>"); int id = rg_sex.getCheckedRadioButtonId(); if(id==R.id.rb_male){//男 sb.append("male"); }else{//女 sb.append("female"); } sb.append("</sex>"); sb.append("</student>");
fos.write(sb.toString().getBytes()); fos.close(); Toast.makeText(this, "保存数据成功", 0).show(); } catch (Exception e) { e.printStackTrace(); Toast.makeText(this, "保存数据失败", 0).show(); } } }
运行代码布署到模拟器上,然后我们在/data/data/com.itheima.studentinfo/files目录下,找到了10001.xml文件如下图:
把10001.xml文件导出到电脑上,使用浏览器打开如下图:
上面是建立xml文件比较传统的方法,但是输入姓名 、学号等信息的时候,我们不能包含非法字符,比如“ /”、“ < ”等等类似,所以上面代码还是有缺陷的。如下图:
使用浏览器打开生成的10002.xml文件报如下错误:
很明显上面传统的xml文件的创建方式是具有很大局限性,但是google的api提供很方便的接口生成xml文件,而且不用考虑这些非法字符,所以很方便安全,下面就介绍:
3.利用google提供API创建xml文件,修改上面的代码如下,这一次我们布署程序到真机中:
package com.itheima.studentinfo; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.InputStream; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlSerializer; import android.app.Activity; import android.os.Bundle; import android.text.TextUtils; import android.util.Xml; import android.view.View; import android.view.Window; import android.widget.EditText; import android.widget.LinearLayout; import android.widget.RadioGroup; import android.widget.TextView; import android.widget.Toast; public class MainActivity extends Activity { private EditText et_name; private EditText et_num; private RadioGroup rg_sex; //显示结果的页面 private LinearLayout ll_result; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //界面无标题 requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.activity_main); et_name = (EditText) findViewById(R.id.et_name); et_num = (EditText) findViewById(R.id.et_num); rg_sex = (RadioGroup) findViewById(R.id.rg_sex); ll_result = (LinearLayout) findViewById(R.id.ll_result); refreshData(); } //刷新数据 private void refreshData() { //清除旧的全部的数据 ll_result.removeAllViews(); //解析已经存在的xml文件,把里面的数据全部都获取出来,添加上到界面上 File files = getFilesDir(); for(File file :files.listFiles()){ //每个文件都是一个xml //解析xml readXmlInfo(file); } } /** * 点击保存学生的信息,生成一个xml文件 * @param view */ public void save(View view){ String name = et_name.getText().toString().trim(); String num = et_num.getText().toString().trim(); if(TextUtils.isEmpty(num)||TextUtils.isEmpty(name)){ Toast.makeText(this, "学生姓名或者学号不能为空", 0).show(); return ; } try { File file = new File(getFilesDir(),num+".xml"); FileOutputStream os = new FileOutputStream(file); //采用谷歌api 生成xml文件 //1.获取一个xml文件的生成器,序列化器 XmlSerializer serializer = Xml.newSerializer(); //2.初始化序列化器 设置写到哪个文件,采用什么样的编码方式 serializer.setOutput(os, "utf-8"); //3.开始写数据 ,写xml文件头,文档为独立的xml文件 serializer.startDocument("utf-8", true); serializer.startTag(null, "student"); serializer.startTag(null, "name"); serializer.text(name); serializer.endTag(null, "name"); serializer.startTag(null, "num"); serializer.text(num); serializer.endTag(null, "num"); serializer.startTag(null, "sex"); if(rg_sex.getCheckedRadioButtonId()==R.id.rb_male){ serializer.text("male"); }else{ serializer.text("female"); } serializer.endTag(null, "sex"); serializer.endTag(null, "student"); serializer.endDocument(); os.close(); Toast.makeText(this, "保存数据成功", 0).show(); refreshData(); } catch (Exception e) { e.printStackTrace(); Toast.makeText(this, "保存数据失败", 0).show(); } } private void readXmlInfo(File file){ try { //1.初始化解析器 XmlPullParser parser = Xml.newPullParser(); //2.设置解析器的参数 InputStream inputStream = new FileInputStream(file); parser.setInput(inputStream, "utf-8"); int type = parser.getEventType(); StringBuilder sb = new StringBuilder(); while(type!=XmlPullParser.END_DOCUMENT){ switch (type) { case XmlPullParser.START_TAG: if("name".equals(parser.getName())){ //这是name节点 String name = parser.nextText(); sb.append("--name:"+name); }else if("num".equals(parser.getName())){ //这是name节点 String num = parser.nextText(); sb.append("--num:"+num); }else if("sex".equals(parser.getName())){ //这是name节点 String sex = parser.nextText(); sb.append("--sex:"+sex); } break; } type = parser.next();//让解析器解析下一个元素 } inputStream.close(); String text = sb.toString(); TextView tv = new TextView(this); tv.setText(text); ll_result.addView(tv); } catch (Exception e) { e.printStackTrace(); TextView tv = new TextView(this); tv.setText("这条数据无效"); ll_result.addView(tv); } } }
序列化器:是将内存写入到文件中
##生成xml文件的步骤
(1). 初始化一个xml的序列化器
XmlSerializer serializer = Xml.newSerializer();
(2). 设置序列化器的参数
serializer.setOutput(os, "utf-8");
(3). 写数据
serializer.startDocument("utf-8", true); 写文档头
serializer.endDocument();写文档末尾
serializer.startTag(命名空间,数据);写某个标签
serializer.endTag(null, "num");
serializer.text()写文本数据
如下:
serializer.startDocument("utf-8", true);//xml文件开始
serializer.startTag(null, "student");//节点开始标签:<student>
serializer.startTag(null, "name");//节点开始标签:<name>
serializer.text(name);
serializer.endTag(null, "name");//节点结束标签:</name>
serializer.startTag(null, "num");//节点开始标签:<num>
serializer.text(num);
serializer.endTag(null, "num");//节点结束标签:</num>
serializer.startTag(null, "sex");//节点开始标签:<sex>
if(rg_sex.getCheckedRadioButtonId()==R.id.rb_male){
serializer.text("male");
}else{
serializer.text("female");
}
serializer.endTag(null, "sex");//节点结束标签:</sex>
serializer.endTag(null, "student");//节点结束标签:</student>
serializer.endDocument();//xml文件结束
os.close();//关闭流
4.刚刚在3中我们生成了xml文件,接下来当然是如何使用面向对象的思想解析这些xml文件:
(1)sax 基于事件
(2)dom & dom4j 把xml文件加载到内存中
(3)pull解析(类似于sax但是效率更高,内存开销更小),Android中常用的xml解析方法。