Android笔记之xml(SAX)解析

来源:互联网 发布:电力系统短路计算软件 编辑:程序博客网 时间:2024/04/28 00:49

Android的xml SAX解析的原理是逐行解析,然后调用相应的函数。

ContentHandler接口中主要用到的函数有:

  • 解析文档开始 startDocument()
  • 解析文档结束 endDocument()
  • 解析标签开始 startElement(String uri, String localName, String qName, Attributes atts)
  • 解析标签结束 endElement(Stringuri, StringlocalName, String qName)
  • 解析标签内容 characters(char[] ch, int start, int length)
由于实现接口必须重写所有方法,所以我们选择继承DefaultHandler这个类,DefaultHandler是对ContentHandler接口中所有方法
的空实现,就是所谓的适配器模式。

首先先看一下我们要解析的testxml.xml
<?xml version="1.0" encoding="UTF-8"?><workers><worker id="AQ01"><name>Mark</name><sex>男</sex><status>经理</status><address>北京</address><money>4000</money></worker><worker id="AD02"><name>lucy</name><sex>女</sex><status>员工</status><address>上海</address><money>1000</money></worker><worker id="AD03"><name>lily</name><sex>女</sex><status>员工</status><address>北京</address><money>3000</money></worker></workers>

我把testxml.xml放在res/raw/testxml.xml,raw文件夹需要自己建。
(不要放在xml目录,因为我只是以字符串的方式读入)
//读取res/raw/testxml.xml并转换成字符串InputStream inputStream = getResources().openRawResource(R.raw.testxml);String resultStr = getString(inputStream);System.out.println(resultStr); 
这个方法是将输入的InputStream转化成字符串,网上看到的http://blog.csdn.net/barryhappy/article/details/7365271
其中inputStreamReader = new InputStreamReader(inputStream, "utf-8");"utf-8"要用自己xml文件的编码
/** * 输入一个inputStream返回字符串 */public static String getString(InputStream inputStream) {    InputStreamReader inputStreamReader = null;    try {        inputStreamReader = new InputStreamReader(inputStream, "utf-8");    } catch (UnsupportedEncodingException e1) {        e1.printStackTrace();    }    BufferedReader reader = new BufferedReader(inputStreamReader);    StringBuffer sb = new StringBuffer("");    String line;    try {        while ((line = reader.readLine()) != null) {            sb.append(line);            sb.append("\n");        }    } catch (IOException e) {        e.printStackTrace();    }    return sb.toString();}
主Activity的完整代码XMLActivity.java,getString()方法懒得封装了,就直接丢进主代码里面
package com.example.xml;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import org.xml.sax.InputSource;import org.xml.sax.SAXException;import org.xml.sax.XMLReader;import java.io.BufferedReader;import java.io.File;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.io.StringReader;import java.io.UnsupportedEncodingException;import javax.xml.parsers.SAXParserFactory;public class XMLActivity extends AppCompatActivity {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.main);        //读取res/raw/.xml并转换成字符串        InputStream inputStream = getResources().openRawResource(R.raw.testxml);        String resultStr = getString(inputStream);        System.out.println(resultStr);        try {            SAXParserFactory factory = SAXParserFactory.newInstance();            XMLReader reader = factory.newSAXParser().getXMLReader();            reader.setContentHandler(new MyContentHandler());            reader.parse(new InputSource(new StringReader(resultStr)));        } catch (Exception e) {            e.printStackTrace();        }    }    /**     * 输入一个inputStream返回字符串     */    public static String getString(InputStream inputStream) {        InputStreamReader inputStreamReader = null;        try {            inputStreamReader = new InputStreamReader(inputStream, "utf-8");        } catch (UnsupportedEncodingException e1) {            e1.printStackTrace();        }        BufferedReader reader = new BufferedReader(inputStreamReader);        StringBuffer sb = new StringBuffer("");        String line;        try {            while ((line = reader.readLine()) != null) {                sb.append(line);                sb.append("\n");            }        } catch (IOException e) {            e.printStackTrace();        }        return sb.toString();    }}


下面是看mars的视频教学打的MyContentHandler.java

package com.example.xml;import org.xml.sax.Attributes;import org.xml.sax.SAXException;import org.xml.sax.helpers.DefaultHandler;public class MyContentHandler extends DefaultHandler {    String hisname, address, money, sex, status;    String tagName;    int i=0;    boolean flag;    @Override    public void startDocument() throws SAXException {        System.out.println("``````````begin``````````");    }    @Override    public void endDocument() throws SAXException {        System.out.println("``````````end``````````");    }    @Override    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {        flag = true;        tagName = localName;        if(localName.equals("worker")) {            for(int i=0; i<attributes.getLength(); i++) {                System.out.println(attributes.getLocalName(i) + "=" + attributes.getValue(i));            }        }    }    @Override    public void endElement(String uri, String localName, String qName) throws SAXException {        flag = false;        if(localName.equals("worker")) {            this.printout();        }    }    private void printout() {        System.out.print("name: ");        System.out.println(hisname);        System.out.print("sex: ");        System.out.println(sex);        System.out.print("status: ");        System.out.println(status);        System.out.print("address: ");        System.out.println(address);        System.out.print("money: ");        System.out.println(money);        System.out.println();    }    /**     * characters并不是只执行一次,只有在startElement和endElement之间的那一次才是正确的     * 所以设置一个flag     */    @Override    public void characters(char[] ch, int start, int length) throws SAXException {        //System.out.println(i++);        if(flag) {            if (tagName.equals("name"))                hisname = new String(ch, start, length);            else if (tagName.equals("sex"))                sex = new String(ch, start, length);            else if (tagName.equals("status"))                status = new String(ch, start, length);            else if (tagName.equals("address"))                address = new String(ch, start, length);            else if (tagName.equals("money"))                money = new String(ch, start, length);        }    }}
这里主要是characters()这个方法并不是在解析每个标签中只执行一次,是个坑,

在一个标签解析结束执行endElement后,和在下一个标签解析开始之前,如果碰到"\t"、"\n"之类的characters()也会执行,

视频教学并没有提到。

找了好久才找到一片文章提到这个问题,原文http://blog.csdn.net/feng88724/article/details/7013675

我的解决方法是,既然在startElement和endElement之间执行的characters()获取的数据才是正确的,

那么设个flag,来控制characters()往变量赋值。


1 0
原创粉丝点击