• Android使用SAX解析xml


    一、理论准备

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

        DOM标准简单易用,但是它需要一次性地读取整个XML文档,而且在程序运行期间,整个DOM树常驻内存,导致系统开销过大。SAX解析方式占用内存小,处理速度更快。
        由于DOM一次性将整个XML文档全部读入内存,因此可以随机访问XML文档的每个元素。SAX采用顺序模式来依次读取XML文档,因此无法做到随机访问XML文档的任意元素。

    二、项目结构

                  image框住的是本实例需要的代码。

    三、实例实现

    <?xml version="1.0" encoding="UTF-8"?>
    
    	
    		Jack
    		24
    	
    	
    		Tom
    		25
    	
    	
    		Bob
    		22
    	

        ps:不知道为啥,用xml格式发布就出问题,用java就不出问题~~愤怒

    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是何意?莫非存在如下情况,费解啊。。。

                           image

  • 相关阅读:
    win10 anaconda 配置
    archlinux yay install termius
    论文新意度
    pytrochgeometric 安装方式
    arch 更新not enough free disk space
    MySQL经典50题
    配置virtualenvwrapper环境
    使用CreateToolHelp32Snapshot函数列出所有进程
    获取任务栏位置
    [转载]C++中的枚举类型支持负数吗?取值范围是多少?
  • 原文地址:https://www.cnblogs.com/hxsyl/p/3648845.html
Copyright © 2020-2023  润新知