Xml 格式数据的生成和解析和 Pull 解析 Xml 格式数据

来源:互联网 发布:js用函数做n的阶乘 编辑:程序博客网 时间:2024/04/29 23:05
Xml 格式数据的生成和解析
使用 xml 作为数据交互的载体是 Android 中非常重要的功能,比如天气预报数据、短信备份数据、通
讯录数据都可以以 xml 的格式通过网络传输。
为了演示 Xml 数据的操作,我模拟了一个短信备份的案例。
需求:界面如图 1-10 所示。上面是三个 Button,前两个分别对应两种不同方式生成 xml,第三个 Button
点击后解析备份的 xml 文件,然后将数据展现在下面的 ScrollView 中。短信数据是模拟的假数据。

生成的 xml 格式如文件

 xml 文件格式<?xml version="1.0" encoding="utf-8" standalone="yes" ?><smses><sms><address>5554</address><body>我是内容<>0</body><time>1445595309201</time></sms><sms><address>5555</address> <body>我是内容<>1</body> <time>1445595309201</time> </sms> ............. </smses>


1.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:orientation="vertical" > <Button android:layout_width="match_parent" android:layout_height="wrap_content" android:onClick="click1" android:text="生成 xml1" /> <Button android:layout_width="match_parent" android:layout_height="wrap_content" android:onClick="click2" android:text="生成 xml2" /> <Button android:layout_width="match_parent" android:layout_height="wrap_content" android:onClick="click3" android:text="解析 xml" /> <ScrollView android:layout_width="match_parent" android:layout_height="wrap_content" > <TextView android:id="@+id/tv_sms" android:layout_width="match_parent" android:layout_height="wrap_content" /> </ScrollView> </LinearLayout>


技能:
在上面布局中首次使用了 ScrollView 控件,其特点如下:
1、只能有一个子节点,但是子节点可以再包含多个子节点,也就是只能有一个孩子,但可以有多个
孙子。
2、当包含的子控件高度超过 ScrollView 的高度时可以垂直滚动子控件。


1.2 拼接字符串方式生成 Xml 文件
【文件 1-12】 MainActivity.java 代码片段
/** 第一种方式生成 xml*/ public void click1(View view) throws Exception { StringBuilder sb = new StringBuilder(); sb.append("<?xml version='1.0' encoding='utf-8' standalone='yes' ?>"); sb.append("<smses>"); for (int i = 0; i < 50; i++) {sb.append("<sms>");sb.append("<address>");sb.append(5554 + i);sb.append("</address>");sb.append("<body>");sb.append("我是短信内容" + i);sb.append("</body>");sb.append("<time>");sb.append(new Date().getTime());sb.append("</time>");sb.append("</sms>"); }sb.append("</smses>"); /* * 使用系统提供的方法 获取文件输出流 */ FileOutputStream fos = this.openFileOutput("info.xml", MODE_PRIVATE); fos.write(sb.toString().getBytes()); fos.close(); }技能:上面的代码虽然也可以生成 xml 文件,但是无法对特殊字符进行处理,比如如果短信内容包含“</>”符号,那么 xml 解析器就无法完成正确的解析。因此使用的前提是你确定数据内容没有特殊字符。1.3 使用 XmlSerializer 生成 Xml 文件
 MainActivity.java 代码片段 /* * 第二种方式生成 xml * 使用 Android 提供的 API */ public void click2(View view) throws Exception { //在 data 目录中创建 info2.xml 文件,获取输出流 FileOutputStream fos = openFileOutput("info2.xml", MODE_PRIVATE); //通过 Xml 类创建一个 Xml 序列化器 XmlSerializer serializer = Xml.newSerializer(); //给序列化器设置输出流和输出流编码 serializer.setOutput(fos, "utf-8"); /* * 让序列化器开发写入 xml 的头信息,其本质是写入内容: * "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>" */ serializer.startDocument("utf-8", true); /* * 开始写入 smses 标签, * 第一个参数是该标签的命名空间, 这里不需要 */serializer.startTag(null, "smses");for (int i = 0; i < 50; i++) {//开始 sms 标签serializer.startTag(null, "sms");//开始 address 标签serializer.startTag(null, "address");//在 address 标签中间写入文本serializer.text("" + (5554 + i));//结束 address 标签serializer.endTag(null, "address");//开始 body 标签serializer.startTag(null, "body");//在 body 标签中间写入文本serializer.text("我是内容<>" + i);//结束 body 标签serializer.endTag(null, "body");serializer.startTag(null, "time");serializer.text(new Date().getTime()+"");serializer.endTag(null, "time");//结束 sms 标签serializer.endTag(null, "sms");}//结束 smses 标签serializer.endTag(null, "smses");//结束文档serializer.endDocument();fos.close();}

注意:

使用 XmlSerializer 生成 xml 文件是推荐的方式,因为该 api 内部已经实现了对特殊字符的处理


使用 Pull 解析 Xml 格式数据
asserts 资源目录中的文件只能读不能写,多用于随 apk 一起发布的固定不变的数据,比如可以将国内
所有的城市列表放在里面。
这里将 1.3 节中生成的 info2.xml 放到 asserts 目录中,然后读取、解析、展现。
 MainActivity.java 代码片段
//使用 pull 解析 xml 数据

public void click3(View v)throws Exception{/** 将解析出来的数据封装在 Sms 中,然后保存到 ArrayList 中* Sms 是自定义的一个 JavaBean*/ArrayList<Sms> smses = null;Sms sms = null;/** 调用父类提供的 getAssets()方法获取 AssertManager 对象*/AssetManager assetManager = getAssets();//使用 assetManager 的 open 方法直接获取输入流对象InputStream inputStream = assetManager.open("info2.xml");//通过 Xml 的静态方法获取 Xml 解析器XmlPullParser parser = Xml.newPullParser();//设置输入流和编码parser.setInput(inputStream, "utf-8");//获取事件类型int event = parser.next();//如果没有解析到文档的结尾,则循环解析while(event!=XmlPullParser.END_DOCUMENT){//获取当前解析到的标签名称String tagName = parser.getName();//如果是“开始标签”事件if (event==XmlPullParser.START_TAG) {//判断当前解析到的开始标签是哪个if ("smses".equals(tagName)) {smses = new ArrayList<Sms>();}else if ("sms".equals(tagName)) {sms = new Sms();}else if ("address".equals(tagName)) {sms.setAddress(parser.nextText());}else if ("body".equals(tagName)) {sms.setBody(parser.nextText());}else if ("time".equals(tagName)) {sms.setTime(parser.nextText());}//如果是“结束标签”事件}else if (event == XmlPullParser.END_TAG) {if ("sms".equals(tagName)) {//如果是 sms 结尾,则将创建的 sms 对象添加到集合中smses.add(sms);}}//继续获取下一个事件event = parser.next();}inputStream.close();//将数据展示到界面showSms(smses);}/** 将短信显示到 TextView 中*/private void showSms(ArrayList<Sms> smses){StringBuilder sb = new StringBuilder();for(Sms s : smses){sb.append(s.toString()+"\n");}tv_sms.setText(sb.toString());}


注意:
在上面的代码中我们不仅学到如何解析 xml,还学到了如何读取 aserts 目录中的数据。

0 0
原创粉丝点击