今天学习Android数据存储——文件存储_SAX解析XML文档
SAX是采用事件驱动,就是说他不需要完全读完xml文件,他是读到一个节点就解析一个节点是否符合xml语法,如果符合就调用相对应的方法其实就是回调方法,并且没有记忆功能。下面提到的这些方法都是在ContentHander()接口中的方法:
startDocumnet() :当开始解析xml文件的声明的时候就会触发这个事件, 可以做一些初始化的工作
startElement() 当开始解析元素的开始标签的时候,就会触发这个事件
characters() 当读到文本元素的时候要触发这个事件.
endElement() 当读到结束标签的时候 就会触发这个事件
SAX就是这样按照顺序来解析的。
实例:SAX读取\mnt\sdcard\mldndata\member.xml
XML布局:
<TableLayout 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"
tools:context=".MyDOMDemo" >
<TableRow >
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="20sp"
android:text="姓名:"/>
<TextView
android:id="@+id/name"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</TableRow>
<TableRow >
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="20sp"
android:text="邮箱:"/>
<TextView
android:id="@+id/email"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</TableRow>
<TableRow >
<Button
android:id="@+id/but"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="读取"/>
</TableRow>
</TableLayout>
Java代码:
保存数据的类:
/**
* DOM解析本身可以支持文件的读取和修改,
* 但是DOM最大的问题就是在于DOM操作中所有内容要一次性全部读取出来,
* 如果文件内容较大,这种读取非常可怕,所以在使用XML解析时往往用SAX方式解析。
*
* 如果想用SAX解析member.xml
* 那么首先需要定义一个保存数据的类LinkMan
* 每一个LinkMan类的对象都表示一条LinkMan节点的内容
*/
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;
}
}
SAX解析器类:
/**
* SAX解析肯定首先需要一个解析器,继承自DefaultHandler类
*/
public class MySAX extends DefaultHandler {
private List<LinkMan> all = null; //保存多条数据
private LinkMan man = null;
private String elementName = null; //保存节点名称
//开始解析文档
@Override
public void startDocument() throws SAXException {
this.all=new ArrayList<LinkMan>(); //表示开始解析文档,所以要设置集合
}
//开始解析元素
@Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
if("linkman".equals(localName)){ //是一个linkman节点,常量在前避免空指向
this.man = new LinkMan(); //实例化LinkMan对象
}
this.elementName = localName; //保存元素名称
}
//解析文本元素
@Override
public void characters(char[] ch, int start, int length)
throws SAXException {
if(this.elementName!=null){ //已经取得了元素名称
String data = new String(ch,start,length);
if("name".equals(this.elementName)){
this.man.setName(data);
}
else if("email".equals(this.elementName)){
this.man.setEmail(data);
}
}
}
//结束解析元素
@Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
if("linkman".equals(localName)){
this.all.add(this.man);
this.man = null; //准备保存下次数据
}
this.elementName = null; //把元素名称清空
}
//取得全部节点内容
public List<LinkMan> getAll() {
return all;
}
}
SAX解析XML测试:
public class MyDOMDemo extends Activity {
private TextView name = null;
private TextView email = null;
private Button but = null;
@Override
protected 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) {
/**
* SAX读取xml文件
*/
if(!Environment.getExternalStorageState().equals(
Environment.MEDIA_MOUNTED)){//SD卡不存在则不操作
return;//返回到程序的被调用处
}
File file = new File(Environment.getExternalStorageDirectory()
+File.separator+"mldndata"+File.separator
+"member.xml");//要输出的文件路径
if(!file.exists()){//文件不存在
return;
}
SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser parser = null;
MySAX sax = new MySAX();
try {
parser = factory.newSAXParser();
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
}
try {
parser.parse(file, sax);
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
//由于此时只有一个节点,所以直接使用了all(0)的形式读取数据
List<LinkMan> all = sax.getAll();
System.out.print(all.size());
MyDOMDemo.this.name.setText(all.get(0).getName());
MyDOMDemo.this.email.setText(all.get(0).getEmail());
}
}
}
读取结果: