Android数据存储——2.文件存储_D_SAX解析XML文档

今天学习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());
                }
        }
}
读取结果:




posted @ 2013-04-15 16:00  魅惑之眼  阅读(132)  评论(0编辑  收藏  举报