首页 > 系统 > Android > 正文

Android笔记之xml(SAX)解析

2019-11-07 23:08:46
字体:
来源:转载
供稿:网友

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()往变量赋值。


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表