xml的三种解析

2.1 SAX

SAX(Simple API for XML) 使用流式处理的方式,它并不记录所读内容的相关信息。

它是一种以事件为驱动的XML API,解析速度快,占用内存少。使用回调函数来实现。

缺点是不能倒退。

2.2 DOM

DOM(Document Object Model) 是一种用于XML文档的对象模型,可用于直接访问 XML 文档的各个部分。

它是一次性全部将内容加载在内存中,生成一个树状结构,它没有涉及回调和复杂的状态管理。

缺点是加载大文档时效率低下。

2.3 PULL

Pull 内置于 Android 系统中。也是官方解析布局文件所使用的方式。

Pull 与 SAX 有点类似,都提供了类似的事件,如开始元素和结束元素。

不同的是,SAX 的事件驱动是回调相应方法,需要提供回调的方法,而后在 SAX 内部自动调用相应的方法。

而Pull解析器并没有强制要求提供触发的方法。因为他触发的事件不是一个方法,而是一个数字。它使用方便,效率高。

三、比较

SAX、DOM、Pull 的比较:

内存占用:SAX、Pull比DOM要好;

编程方式:SAX 采用事件驱动,在相应事件触发的时候,会调用用户编好的方法,也即每解析一类 XML,就要编写一个新的适合该类XML的处理类。DOM 是 W3C 的规范,Pull 简洁。

访问与修改:SAX 采用流式解析,DOM 随机访问。

访问方式:SAX,Pull 解析的方式是同步的,DOM 逐字逐句。

四、使用举例


  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <persons>  
  3.   <person id="23">  
  4.     <name>李明</name>  
  5.     <age>30</age>  
  6.   </person>  
  7.   <person id="20">  
  8.     <name>李向梅</name>  
  9.     <age>25</age>  
  10.   </person>  
  11. </persons>  

4.1 SAX 解析举例

[java]  view plain  copy
  1. public static List<Person> readXML(InputStream inStream) {  
  2.    try {  
  3.             //创建解析器  
  4.             SAXParserFactory spf = SAXParserFactory.newInstance();  
  5.             SAXParser saxParser = spf.newSAXParser();  
  6.    
  7.             //设置解析器的相关特性,true表示开启命名空间特性  
  8.             saxParser.setProperty("http://xml.org/sax/features/namespaces",true);  
  9.             XMLContentHandler handler = new XMLContentHandler();  
  10.             saxParser.parse(inStream, handler);  
  11.             inStream.close();  
  12.   
  13.             return handler.getPersons();  
  14.    } catch (Exception e) {  
  15.             e.printStackTrace();  
  16.    }  
  17.   
  18.   return null;  
  19. }  
  20.   
  21.    
  22. //SAX类:DefaultHandler,它实现了ContentHandler接口。在实现的时候,只需要继承该类,重载相应的方法即可。  
  23. public class XMLContentHandler extends DefaultHandler {  
  24.   
  25.             private List<Person> persons = null;  
  26.             private Person currentPerson;  
  27.             private String tagName = null;//当前解析的元素标签  
  28.   
  29.              public List<Person> getPersons() {  
  30.                         return persons;  
  31.             }  
  32.    
  33.             //接收文档开始的通知。当遇到文档的开头的时候,调用这个方法,可以在其中做一些预处理的工作。  
  34.             @Override  
  35.             public void startDocument() throws SAXException {  
  36.                         persons = new ArrayList<Person>();  
  37.             }  
  38.   
  39.              //接收元素开始的通知。当读到一个开始标签的时候,会触发这个方法。其中namespaceURI表示元素的命名空间;  
  40.             //localName表示元素的本地名称(不带前缀);qName表示元素的限定名(带前缀);atts 表示元素的属性集合  
  41.             @Override  
  42.             public void startElement(String namespaceURI, String localName, String qName, Attributes atts) throws SAXException {  
  43.   
  44.                         if(localName.equals("person")){  
  45.                                     currentPerson = new Person();  
  46.                                     currentPerson.setId(Integer.parseInt(atts.getValue("id")));  
  47.                         }  
  48.   
  49.                         this.tagName = localName;  
  50.             }  
  51.    
  52.             //接收字符数据的通知。该方法用来处理在XML文件中读到的内容,第一个参数用于存放文件的内容,  
  53.             //后面两个参数是读到的字符串在这个数组中的起始位置和长度,使用new String(ch,start,length)就可以获取内容。  
  54.             @Override  
  55.             public void characters(char[] ch, int start, int length) throws SAXException {  
  56.   
  57.                         if(tagName!=null){  
  58.                                     String data = new String(ch, start, length);  
  59.                                     if(tagName.equals("name")){  
  60.                                                 this.currentPerson.setName(data);  
  61.                                     }else if(tagName.equals("age")){  
  62.                                                 this.currentPerson.setAge(Short.parseShort(data));  
  63.                                     }  
  64.                         }  
  65.             }  
  66.   
  67.              //接收文档的结尾的通知。在遇到结束标签的时候,调用这个方法。其中,uri表示元素的命名空间;  
  68.             //localName表示元素的本地名称(不带前缀);name表示元素的限定名(带前缀)  
  69.             @Override  
  70.             public void endElement(String uri, String localName, String name) throws SAXException {  
  71.   
  72.                         if(localName.equals("person")){  
  73.                                     persons.add(currentPerson);  
  74.                                     currentPerson = null;  
  75.                         }  
  76.   
  77.                         this.tagName = null;  
  78.             }  
  79. }  

4.2 DOM 解析举例

public class DomPersonService {
    /**
     * @param inStream
     * @return
     * @throws Exception
     */
    public static List<Person> getPersons(InputStream inStream)
            throws Exception {

        List<Person> persons = new ArrayList<Person>();
        /**
         * 文檔的解析
         */
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = factory.newDocumentBuilder();
        Document document = builder.parse(inStream);
        /**
         * 操作對象樹
         */
        Element root = document.getDocumentElement();//返回文檔的根元素
        NodeList personNodes = root.getElementsByTagName("person");
        for (int i = 0; i < personNodes.getLength(); i++) {
            Element personElement = (Element) personNodes.item(i);
            int id = new Integer(personElement.getAttribute("id"));
            Person person = new Person();
            person.setId(id);
            NodeList childNodes = personElement.getChildNodes();
            for (int y = 0; y < childNodes.getLength(); y++) {
                if (childNodes.item(y).getNodeType() == Node.ELEMENT_NODE) {
                    if ("name".equals(childNodes.item(y).getNodeName())) {
                        String name = childNodes.item(y).getFirstChild()
                                .getNodeValue();
                        person.setName(name);
                    }
                    else if ("age".equals(childNodes.item(y).getNodeName())) {
                        String age = childNodes.item(y).getFirstChild()
                                .getNodeValue();
                        person.setAge(new Short(age));
                    }
                }
            }
            persons.add(person);
        }
        inStream.close();
        return persons;
    }
}
public void testDOMGetPersons() throws Throwable {
    InputStream inStream = this.getClass().getClassLoader()
        .getResourceAsStream("person.xml");
    List<Person> persons = DomPersonService.getPersons(inStream);
    for (Person person : persons) {
        Log.i(TAG, person.toString());
     }
}

4.3 PULL解析举例

public class PullPersonService {

    /**
     * ------------------------使用PULL解析XML-----------------------
     * @param inStream
     * @return
     * @throws Exception
     */
    public static List<Person> getPersons(InputStream inStream)
            throws Exception {
        Person person = null;
        List<Person> persons = null;
        XmlPullParser pullParser = Xml.newPullParser();
        pullParser.setInput(inStream, "UTF-8");
        int event = pullParser.getEventType();// 觸發第一個事件
        while (event != XmlPullParser.END_DOCUMENT) {
            switch (event) {
            case XmlPullParser.START_DOCUMENT:
                persons = new ArrayList<Person>();
                break;
            case XmlPullParser.START_TAG:
                if ("person".equals(pullParser.getName())) {
                    int id = new Integer(pullParser.getAttributeValue(0));
                    person = new Person();
                    person.setId(id);
                }
                if (person != null) {
                    if ("name".equals(pullParser.getName())) {
                        person.setName(pullParser.nextText());
                    }
                    if ("age".equals(pullParser.getName())) {
                        person.setAge(new Short(pullParser.nextText()));
                    }
                }
                break;
            case XmlPullParser.END_TAG:
                if ("person".equals(pullParser.getName())) {
                    persons.add(person);
                    person = null;
                }
                break;
            }
            event = pullParser.next();
        }
        return persons;
    }
}
public void testPullGetPersons() throws Throwable {
    InputStream inStream = this.getClass().getClassLoader()
            .getResourceAsStream("person.xml");
    List<Person> persons = PullPersonService.getPersons(inStream);
    for (Person person : persons) {
        Log.i(TAG, person.toString());
    }
}

发布了77 篇原创文章 · 获赞 3 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/haiyang497661292/article/details/79061812