一、理论准备

    SAX采用事件驱动机制来解析XML文档,每当SAX解析器发现文档开始、元素开始、文本、元素结束、文档结束等事件时,就会向外发送一次事件,而开发者则可以通过编写事件监听器处理这些事件,以此来获取XML文档里的信息。

    DOM标准简单易用,但是它需要一次性地读取整个XML文档,而且在程序运行期间,整个DOM树常驻内存,导致系统开销过大。SAX解析方式占用内存小,处理速度更快。

    由于DOM一次性将整个XML文档全部读入内存,因此可以随机访问XML文档的每个元素。SAX采用顺序模式来依次读取XML文档,因此无法做到随机访问XML文档的任意元素。

二、项目结构

              Android使用SAX解析xml_java框住的是本实例需要的代码。

三、实例实现

<?xml version="1.0" encoding="UTF-8"?>
Jack24Tom25Bob22


    ps:不知道为啥,用xml格式发布就出问题,用java就不出问题~~Android使用SAX解析xml_xml_02


package xml;

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

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

public class SaxService {
public static List readXML(InputStream inputStream) throws Exception {
SAXParserFactory spf = SAXParserFactory.newInstance(); //创建SAXParserFactory对象(SAX解析器工厂)
SAXParser saxParser = spf.newSAXParser(); //创建SAXParser对象(SAX解析器)
MyDefaultHandle myDefaultHandle = new MyDefaultHandle(); //MyDefaultHandle对象,继承自DefaultHandle类
saxParser.parse(inputStream, myDefaultHandle); //解析XML文档(以InputStream对象的形式)
inputStream.close(); //关闭InputStream对象
return myDefaultHandle.getPersonList(); //返回XML文档中的数据列表
}
}

package xml;

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

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

public class MyDefaultHandle extends DefaultHandler {
private Person person = null; //存储解析得到的单个Person对象
private List personList = null; //存储解析得到的所有Person对象
private String currentTag = null; //正在解析的元素的标签

private static final String TAG = "MyDefaultHandle"; //Log标签

public List getPersonList() {
return personList;
}

public void startDocument() throws SAXException {
personList = new ArrayList();
System.out.println("开始解析");
}

public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
if(qName.equals("person")) { //当遇到标签时,创建一个Person对象
person = new Person();
if(attributes!=null) {
person.setId(Integer.parseInt(attributes.getValue(0)));//将读到的id属性值存入Person对象
}
System.out.println("处理标签");
}

currentTag = qName; //设置当前读到的标签
}

public void characters(char[] ch, int start, int length) throws SAXException {
String currentValues = new String(ch, start, length); //获取当前标签里的内容
if(currentTag != null) {
if(currentTag.equals("name")) { //将读到的name属性值存入Person对象
person.setName(currentValues);
}else if(currentTag.equals("age")) { //将读到的age属性值存入Person对象
person.setAge(Integer.parseInt(currentValues));
}
System.out.println("处理元素");
}
}

public void endElement(String uri, String localName, String qName) throws SAXException {
//当读到标签时,向列表中添加读取到的单个Person对象
if(qName.equals("person") && (person != null)) {
personList.add(person);
person = null;
System.out.println("添加一个person");
}
currentTag = null;
}

public void endDocument() throws SAXException {
System.out.println("完毕");
}

}

package xml;

public class Person {
private String name;
private int age;
private int id;

public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}

     不知道咋回事Test类就是插不进去,显示一半,气死了。。直接看吧

package xml;

import java.io.IOException;

import java.io.InputStream;

import java.net.HttpURLConnection;

import java.net.MalformedURLException;

import java.net.URL;

import java.util.List;

public class Test {

    static String URL_PATH = "​​http://localhost:8080/TestGet/person.xml";​

   

    public static InputStream getInputStream() throws IOException {

        InputStream inputStream = null;

        HttpURLConnection httpURLConnection = null;

        try {

            URL url = new URL(URL_PATH);

            if (url != null) {

                httpURLConnection = (HttpURLConnection) url.openConnection();

                // 设置连接网络的超时时间

                httpURLConnection.setConnectTimeout(3000);

                httpURLConnection.setDoInput(true);

                // 设置本次http请求使用get方式请求

                httpURLConnection.setRequestMethod("GET");

                int responseCode = httpURLConnection.getResponseCode();

                if (responseCode == 200) {

                    // 从服务器获得一个输入流

                    inputStream = httpURLConnection.getInputStream();

                }

            }

        } catch (MalformedURLException e) {

            // TODO Auto-generated catch block

            e.printStackTrace();

        }

 

        return inputStream;

    }

    public static void main(String[] args) throws IOException, Exception {

        // TODO Auto-generated method stub

        if(getInputStream()==null) {

            System.out.println("读取失败");

            return ;

        }

        List<Person> person = SaxService.readXML(getInputStream());

        System.out.println(person.size());

        for(int i=0; i<person.size(); i++)

            System.out.println("id:"+person.get(i).getId()+"age:"+person.get(i).getAge()

                    +"name:"+person.get(i).getName());

    }

}


    结果如下:

开始解析
处理元素
处理标签
处理元素
处理元素
处理元素
添加一个person
处理标签
处理元素
处理元素
处理元素
添加一个person
处理标签
处理元素
处理元素
处理元素
添加一个person
完毕
3
id:1age:24name:Jack
id:2age:25name:Tom
id:3age:22name:Bob

四、遗留问题

    1.sax解析中Name和localName什么区别,想到这个是因为一哥们用的localName和person判断他表示结果对了,费解???

    2.endElement的if里把person设置为null是为了防止重复触发该事件,之后把currentTag设置为null是何意?莫非存在如下情况,费解啊。。。

                       Android使用SAX解析xml_sax解析_03


作者:​​火星十一郎​

本文版权归作者火星十一郎所有,欢迎转载和商用,但未经作者同意必须保留此段声明,且​