zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    ....
    CodeForces 375A(同余)
    POJ 2377 Bad Cowtractors (最小生成树)
    POJ 1258 AgriNet (最小生成树)
    HDU 1016 Prime Ring Problem(全排列)
    HDU 4460 Friend Chains(bfs)
    POJ 2236 Wireless Network(并查集)
    POJ 2100 Graveyard Design(尺取)
    POJ 2110 Mountain Walking(二分/bfs)
    CodeForces 1059B Forgery(模拟)
  • 原文地址:https://www.cnblogs.com/hxsyl/p/3648845.html
Copyright © 2011-2022 走看看