数据存储:Pull解析
【定义XML解析的工具类---MyXMLPullUtil.java】
import java.io.InputStream; import java.util.ArrayList; import java.util.List; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserFactory; public class MyXMLPullUtil { private InputStream input = null ; public MyXMLPullUtil(InputStream input) { this.input = input ; } public List<LinkMan> getAllLinkMan() throws Exception{ List<LinkMan> all = null ; LinkMan man = null ; // 保存节点的名称 String elementName = null ; XmlPullParserFactory factory = XmlPullParserFactory.newInstance() ; XmlPullParser xpp = factory.newPullParser() ; xpp.setInput(this.input, "UTF-8") ; // 取得事件码 int eventType = xpp.getEventType() ; // 不是文档底部 while(eventType != XmlPullParser.END_DOCUMENT) { // 文档开始 if(eventType == XmlPullParser.START_DOCUMENT) { all = new ArrayList<LinkMan>() ; // 元素标记开始 } else if (eventType == XmlPullParser.START_TAG) { // 取得元素的名称 elementName = xpp.getName() ; if("linkman".equals(elementName)) { man = new LinkMan() ; } // 结束元素 } else if (eventType == XmlPullParser.END_TAG) { // 取得节点名称 elementName = xpp.getName() ; if("linkman".equals(elementName)) { all.add(man) ; man = null ; } // 数据 } else if (eventType == XmlPullParser.TEXT) { if("name".equals(elementName)) { man.setName(xpp.getText()) ; } else if ("email".equals(elementName)) { man.setEmail(xpp.getText()) ; } } // 取得下一个事件码 eventType = xpp.next() ; } return all ; } }
本程序中采用了Pull解析操作,程序会从指定的InputStream对象中读取相关的XML数据,而后采用XmlPullParser接口的相关操作方法,使用循环读取出全部所需要的内容。
【定义Activity程序,进行Pull解析】
import java.io.File; import java.io.FileInputStream; import java.io.InputStream; import java.util.List; import android.app.Activity; import android.os.Bundle; import android.os.Environment; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.TextView; public class MyXMLPullDemo extends Activity { private TextView name = null; private TextView email = null; private Button but = null; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); super.setContentView(R.layout.main); this.name = (TextView) super.findViewById(R.id.name); this.email = (TextView) super.findViewById(R.id.email); this.but = (Button) super.findViewById(R.id.but); this.but.setOnClickListener(new OnClickListenerImpl()); } private class OnClickListenerImpl implements OnClickListener { @Override public void onClick(View v) { if (!Environment.getExternalStorageState().equals( Environment.MEDIA_MOUNTED)) { // 不存在不操作 return; // 返回到程序的被调用处 } File file = new File(Environment.getExternalStorageDirectory() + File.separator + "mldndata" + File.separator + "member.xml"); // 要输出文件的路径 if (!file.exists()) { // 文件不存在 return; } try { // 定义输入流 InputStream input = new FileInputStream(file); // 操作Pull工具类 MyXMLPullUtil util = new MyXMLPullUtil(input) ; // 取得联系人信息 List<LinkMan> all = util.getAllLinkMan() ; // 设置文本 MyXMLPullDemo.this.name.setText( all.get(0).getName()) ; // 设置文本 MyXMLPullDemo.this.email.setText( all.get(0).getEmail()) ; } catch (Exception e) { e.printStackTrace(); } } } }
本程序的关键代码就在于传递InputStream对象给MyXMLPullUtil类,并且利用此类中的getAllLinkMan()方法取出全部的联系人信息,而后将信息设置到文本显示组件中显示。
【LinkMan.java】
package org.lxh.demo; public class LinkMan { private String name; private String email; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } }
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
此时已经完成了读取的操作,但是在Android之中这种Pull解析的方式也可以完成像DOM那样的输出功能。
下面为了方便的保存数据,也直接定义一个工具类,现在工具类是将所有要保存的数据都是用List集合定义。
【定义XML解析的工具类---MyXMLPullUtil.java】
import java.io.OutputStream; import java.util.Iterator; import java.util.List; import org.xmlpull.v1.XmlPullParserFactory; import org.xmlpull.v1.XmlSerializer; public class MyXMLPullUtil { // 保存全部数据 private List<LinkMan> all = null; // 定义输出流 private OutputStream output = null; // 构造方法接收 public MyXMLPullUtil(OutputStream output, List<LinkMan> all) { this.output = output; // 取得输出流 this.all = all; // 取得数据 } public void save() throws Exception { XmlPullParserFactory factory = XmlPullParserFactory.newInstance(); // 取得XmlSerializer接口对象 XmlSerializer xs = factory.newSerializer(); // 设置输出编码 xs.setOutput(this.output, "UTF-8"); // 文档开始,编码为UTF-8,且独立运行 xs.startDocument("UTF-8", true); // 定义跟元素开始 xs.startTag(null, "addresslist"); // 取得Iterator接口对象 Iterator<LinkMan> iter = this.all.iterator(); // 迭代输出 while (iter.hasNext()) { LinkMan man = iter.next(); xs.startTag(null, "linkman"); xs.startTag(null, "name"); xs.text(man.getName()); xs.endTag(null, "name"); xs.startTag(null, "email"); xs.text(man.getEmail()); xs.endTag(null, "email"); xs.endTag(null, "linkman"); } // 定义根元素完结 xs.endTag(null, "addresslist"); // 定义文档结束 xs.endDocument(); // 清空缓冲区 xs.flush(); } }
本程序可以直接输出List集合中的多条数据内容。
【定义Activity程序(MyXMLPullDemo.java),向XML中保存多组数据】
import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.util.ArrayList; import java.util.List; import android.app.Activity; import android.os.Bundle; import android.os.Environment; public class MyXMLPullDemo extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); super.setContentView(R.layout.main); if (!Environment.getExternalStorageState().equals( Environment.MEDIA_MOUNTED)) { // 不存在不操作 return; // 返回到程序的被调用处 } File file = new File(Environment.getExternalStorageDirectory() + File.separator + "mldndata" + File.separator + "member.xml"); // 要输出文件的路径 if (!file.getParentFile().exists()) { // 文件不存在 file.getParentFile().mkdirs() ; // 创建文件夹 } List<LinkMan> all = new ArrayList<LinkMan>() ; for (int x = 0; x < 3; x++) { LinkMan man = new LinkMan() ; man.setName("李兴华 - " + x ) ; man.setEmail("mldnqa@163.com") ; all.add(man) ; } // 定义输出流 OutputStream output = null ; try { // 定义文件输出流 output = new FileOutputStream(file) ; // 生成XML文件 new MyXMLPullUtil(output,all).save() ; } catch (Exception e) { }finally{ // 输出流对象不为空 if (output != null) { try { // 关闭输出流 output.close() ; } catch (IOException e) { e.printStackTrace(); } } } } }
【LinkMan.java】
package org.lxh.demo; public class LinkMan { private String name; private String email; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } }
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
本程序没有定义布局文件,所以要保存在XML文件中的数据通过LinkMan类进行了封装,并保存到List集合中,而后通过指定的输出流输出数据,数据保存成功后的文件内容。
<?xml version='1.0' encoding='UTF-8' standalone='yes' ?> <addresslist> <linkman> <name>刘德华-0</name> <email>dehua@126.com</email> </linkman> <linkman> <name>刘德华-1</name> <email>dehua@126.com</email> </linkman> <linkman> <name>刘德华-2</name> <email>dehua@126.com</email> </linkman> </addresslist>
Pull解析器和SAX解析器虽有区别但也有相似性。他们的区别为:SAX解析器的工作方式是自动将事件推入注册的事件处理器进行处理,因此你不能控制事件的处理主动结束;而Pull解析器的工作方式为允许你的应用程序代码主动从解析器中获取事件,正因为是主动获取事件,因此可以在满足了需要的条件后不再获取事件,结束解析。这是他们主要的区别。