android解析xml-用sax解析

sax解析xml是一个事件驱动的xml解析器结构,当发生了startDocument,startElement事件都会触发响应事件回调函数进行响应。
sax默认的事件响应回调接口是contentHandler,定义了一序列的事件响应接口函数,

  1. startDocumet/endDocument在文档开始和结束时候回调这个函数,一般用于文档解析的初始化和结尾数据整理。
  2. startElement/endElement通知一个元素的开始和结束,Attributes在startElement中以参数形式将这个元素的所有属性传递进来。
  3. Attributes属性定义了getValue(i)/getValue(String qname)/getValue(url, localName);返回第i个或者指定属性名称的属性值;
  4. getLength()返回属性的个数
  5. getQName(i) /getLocalName(i)/getURI(I)返回限定名,本地名,名称空间
    定义一个javabean用于从xml实例化过来的实例
package com.vincent.org.networkapp.xml;


/**
 * xml解析的操作数据实体
 * 
 * @author cindy
 * 
 */
public class Person {
    private Integer id;

    private String name;

    private Short age;

    public Person() {
        // TODO Auto-generated constructor stub
    }

    public Person(Integer id, String name, Short age) {
        super();
        this.id = id;
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return "Peron [id=" + id + ", name=" + name + ", age=" + age + "]";
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Short getAge() {
        return age;
    }

    public void setAge(Short age) {
        this.age = age;
    }

}

定义个handler,就是xml文件的事件处理器

package com.vincent.org.networkapp.xml.saxservice;

import java.util.ArrayList;
import java.util.List;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

import android.util.Log;

import com.vincent.org.networkapp.xml.Person;

/**
 * sax是事件驱动式的xml解析器
 * 
 * @author cindy
 * 
 */
public class SaxHandler extends DefaultHandler {

    private static final String TAG = "SAXHandler";
    private List<Person> persons;

    public List<Person> getPersons() {
        return persons;
    }

    private String perTag;// 记录当前标签的名字
    Person person;// 记录当前解析的person

    // 开始解析回调
    @Override
    public void startDocument() throws SAXException {
        // TODO Auto-generated method stub
        super.startDocument();
        persons = new ArrayList<Person>();
        Log.i(TAG, "---startDoucument() begin parse---");
    }

    @Override
    public void endDocument() throws SAXException {
        // TODO Auto-generated method stub
        super.endDocument();
        Log.i(TAG, "---endDoucument() stop parse---");

    }

    @Override
    public void startElement(String uri, String localName, String qName,
            Attributes attributes) throws SAXException {
        // TODO Auto-generated method stub
        super.startElement(uri, localName, qName, attributes);
        if ("person".equals(localName)) {
            for (int i = 0; i < attributes.getLength(); i++) {
                Log.i(TAG, "attributesName: " + attributes.getLocalName(i)
                        + " attributes_value:" + attributes.getValue(i));
                person = new Person();
                person.setId(Integer.valueOf(attributes.getValue(i)));
            }

        }
        perTag = localName;
        Log.i(TAG, qName + "---startElement---");

    }

    @Override
    public void endElement(String uri, String localName, String qName)
            throws SAXException {
        // TODO Auto-generated method stub
        super.endElement(uri, localName, qName);
        if ("person".equals(localName)) {
            persons.add(person);
            person = null;
        }// person节点结束
        perTag = null;// 一个节点的结束,包括person节点和name节点
        Log.i(TAG, qName + "---endElement---");
    }

    // 遇到文本节点时候回调这个方法
    @Override
    public void characters(char[] ch, int start, int length)
            throws SAXException {
        // TODO Auto-generated method stub
        super.characters(ch, start, length);
        String data = new String(ch, start, length).trim();

        if (!"".equals(data.trim())) {
            Log.i(TAG, "content: " + data);

            if ("name".equals(perTag)) {
                person.setName(data);

            } else if ("age".equals(perTag)) {
                person.setAge(new Short(data));
            }
        }
    }

}

定义一个xml解析的服务类

package com.vincent.org.networkapp.xml.saxservice;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.SAXException;

import android.util.Log;

import com.vincent.org.networkapp.xml.Person;

public class SaxService {

    private static final String TAG = "SaxService";

    public static List<Person> getPersons(InputStream iStream)
            throws ParserConfigurationException, SAXException, IOException {
        Log.i(TAG, iStream == null ? "istream是空" : "否");
        SAXParserFactory spf = SAXParserFactory.newInstance();
        SAXParser saxParser = spf.newSAXParser();
        SaxHandler handler = new SaxHandler();
        // saxParser.parse(dataXml, handler);
        saxParser.parse(iStream, handler);
        iStream.close();
        return handler.getPersons();
    }
}

然后是页面button触发xml解析事件处理函数。

public void saxXml(View view) throws ParserConfigurationException,
            SAXException, IOException {

        Toast.makeText(this, "saxXml ", Toast.LENGTH_LONG).show();

        List<Person> list = parseXml("Person.xml");
        // List<Person> list = parseXml();
        listView.setAdapter(new ArrayAdapter<Person>(XmlParseActivity.this,
                android.R.layout.simple_list_item_1, android.R.id.text1, list));
        Log.i(TAG_XmlParseActivity, XmlParseActivity.class.getName());
        Log.i(TAG_XmlParseActivity,
                XmlParseActivity.class.getResource("Person.xml").toString());
    }
/**
     * 第一种获取资源的方式,通过getResourceAsStream方式,没有通过android的推荐 获取方式
     * xmlpath制定的xml文件必须和我这个函数所在的activity在同一个包下面。
     * 
     * @param XmlPath
     * @return
     * @throws ParserConfigurationException
     * @throws SAXException
     * @throws IOException
     */
    public List<Person> parseXml(String XmlPath)
            throws ParserConfigurationException, SAXException, IOException {
        // 第一种获取资源的方式
        InputStream iStream = XmlParseActivity.class
                .getResourceAsStream(XmlPath);
        // Toast.makeText(this, iStream.toString(), Toast.LENGTH_LONG).show();
        List<Person> persons = SaxService.getPersons(iStream);

        return persons;

    }

使用的xml文件

<?xml version="1.0" encoding="utf-8"?>
<!-- 数据操作集 -->
<persons>
    <person id="12">
        <name>vincent</name>
        <age>18</age>
    </person>
    <person id="15">
        <age>19</age>
        <name>jack</name>
    </person>
    <person id="16">
        <age>29</age>
        <name>kandy</name>
    </person>
    <person id="17">
        <age>23</age>
        <name>jim</name>
    </person>
    <person id="19">
        <age>24</age>
        <name>tuwen</name>
    </person>
</persons>

最后我要提一个问题,就是上面我获取xml文件流是通过java那种原声加载资源的方式,说白了就是根据classpath的路径下寻找。所以上面那个方法限定了xml文件只能放在引用这个xml文件的源码在同一个包下面。
然后我用下面这个获取xml输入流的方式是将xml文件放在res/xml文件夹下面可以用android原生引用xml文件的方式this.getResources()
.openRawResource(R.xml.person)获取到inputstream,但是解析总是报错。 报错 Caused by: org.apache.harmony.xml.ExpatParser$ParseException: At
line 1, column 0: not well-formed (invalid token)
依据这个http://www.xuebuyuan.com/1903031.html更改后还是不行。希望大神可以指点。

private List<Person> parseXml() throws ParserConfigurationException,
            SAXException, IOException {

        // 第二种获取资源的方式
        /**
         * 报错 Caused by: org.apache.harmony.xml.ExpatParser$ParseException: At
         * line 1, column 0: not well-formed (invalid token)
         */
        InputStream iStream = new BufferedInputStream(this.getResources()
                .openRawResource(R.xml.person));
        // byte[] dataXml = StreamTool.readInputStreamTobyte(iStream);
        InputStreamReader isr = new InputStreamReader(iStream, "GB2312");

        InputSource inputSource = new InputSource(isr);
        // inputSource.setEncoding("GB2312");
        Log.i(TAG_XmlParseActivity, iStream == null ? "istream是null"
                : "istream不是null");
        SAXParserFactory spf = SAXParserFactory.newInstance();
        SAXParser saxParser = spf.newSAXParser();
        SaxHandler handler = new SaxHandler();
        // saxParser.parse(dataXml, handler);
        saxParser.parse(inputSource, handler);
        // XMLReader xmlReader = saxParser.getXMLReader();
        // xmlReader.setContentHandler(handler);
        // xmlReader.parse(inputSource);
        List<Person> persons = handler.getPersons();
        isr.close();

        return persons;
    }
还是报这个错误。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值