zoukankan      html  css  js  c++  java
  • 【Android学习】XML文本的三种解析方式(通过搭建本地的Web项目提供XML文件)

    XML为一种可扩展的标记语言,是一种简单的数据存储语言,使用一系列简单的标记来描述。

    一、SAX解析

      即Simple API for XML,以事件的形式通知程序,对Xml进行解析。

      1、首先在Web项目中发布一个XML文档,名字为persons.xml,具体内容为: 

    <?xml version="1.0" encoding="UTF-8"?>
    <persons>
        <person id="1">
            <name>周杰伦</name>
            <age>20</age>
        </person>
        <person id="2">
            <name>小明</name>
            <age>21</age>
        </person>
    
    </persons>

      2、SAX解析的流程主要如下:

      

      通过创建SAXParserFactory对象获得一个实例,然后再通过工厂获得一个SaxParser,依靠SaxParser的parse方法,完成解析,其中parse方法的参数为一个InputStream类和一个DefaultHandler类,defaultHandler需         要重写

        SAXParserFactory spf = SAXParserFactory.newInstance();
           SAXParser parse = spf.newSAXParser();
           Myhandler handler = new Myhandler("person");
           parse.parse(is, handler);
           list = handler.getList();

      

      3、重写处理类DefaultHandler。

      

      

    
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.List;
    
    import org.xml.sax.Attributes;
    import org.xml.sax.SAXException;
    import org.xml.sax.helpers.DefaultHandler;
    
    public class Myhandler extends DefaultHandler {
    
        List<HashMap<String, String>> list = null;// 存储所有的解析对象
        String currentTag = null; // 正在解析的标签
        String currentValue = null; // 正在解析元素的值
        String nodename = null; // 正在解析节点名称
        HashMap<String, String> map = null;// 存储单个解析的完整对象
    
        public Myhandler(String nodename) {
            this.nodename = nodename;
        }
    
        public List<HashMap<String, String>> getList() {
            return list;
        }
    
        @Override
        // 读到第一个开始标签的时候触发
        public void startDocument() throws SAXException {
    
            list = new ArrayList<HashMap<String, String>>();
        }
    
        @Override
        // 当遇到所要解析的节点名称时触发
        public void startElement(String uri, String localName, String qName,
                Attributes attributes) throws SAXException {
    
            if (qName.equals(nodename)) {
                map = new HashMap<String, String>();
    
            }
    
            if (attributes != null && map != null) {
                for (int i = 0; i < attributes.getLength(); i++) {
                    map.put(attributes.getQName(i), attributes.getValue(i));
                }
            }
    
            currentTag = qName;
    
        }
    
        @Override
        public void endElement(String uri, String localName, String qName)
                throws SAXException {
            if (qName.equals(nodename)) {
                list.add(map);
                map = null;
            }
            super.endElement(uri, localName, qName);
        }
    
        @Override
        // 处理xml文件读取到的内容
        public void characters(char[] ch, int start, int length)
                throws SAXException {
    
            if (currentTag != null && map != null) {
                currentValue = new String(ch, start, length);
                if (currentValue != null && !currentValue.trim().equals("")
                        && !currentValue.trim().equals("
    ")) {
                    map.put(currentTag, currentValue);
                }
    
            }
    
            currentTag = null;
            currentValue = null;
        }
    
    }

      

      

      

      4、通过自定义的HttpUtils类,从服务器获取数据,以流的形式返回,也就是XML文档的输入流,这里不再给出,关于获得服务器数据的三种方式下次会下次更新。

      5、最后通过返回的List<Map<String,String>> 获得了XML文档的所需要的内容,需要提到的是,我在这里是需要解析person节点,于是只有qName等于person时候才会开始解析。

    二、PULL解析

      类似于SAX方式,程序以“拉取”的方式对Xml进行解析。

      1、与SAX解析类似,但比SAX解析容易,需要JAR包,下载地址:

      2、首先通过XMLPullFactory创建一个工厂,然后再由工厂创建一个XMLPullParser对象,由对象进行相关处理。

      3、通过对eventType进行XML文件的节点解析,获得数据,并存放在List中进行返回。

    import java.io.InputStream;
    import java.util.ArrayList;
    import java.util.List;
    
    import org.xmlpull.v1.XmlPullParser;
    import org.xmlpull.v1.XmlPullParserException;
    import org.xmlpull.v1.XmlPullParserFactory;
    
    public class PullXmlHandler {
    
        public static List<Person> parseXml(InputStream is, String encode)
                throws Exception {
            List<Person> list = null;
            Person p = null;
            try {
                XmlPullParserFactory xmlPullF = XmlPullParserFactory.newInstance();
                XmlPullParser parser = xmlPullF.newPullParser();
                parser.setInput(is, encode);
                int eventType = parser.getEventType();
      
            
    //如果还没到文档结束节点就一直循环
    while (eventType != XmlPullParser.END_DOCUMENT) { switch (eventType) { case XmlPullParser.START_DOCUMENT: list = new ArrayList
    <Person>(); break; case XmlPullParser.START_TAG: if (parser.getName().equals("person")) { p = new Person(); if (parser.getAttributeCount() != 0) { p.setId(parser.getAttributeValue(0)); } } else if (parser.getName().equals("name")) { p.setName(parser.nextText()); } else if (parser.getName().equals("age")) { p.setAge(parser.nextText()); } break; case XmlPullParser.END_TAG: if (parser.getName().equals("person")) { list.add(p); p = null; } break; default: break; }         //进行下次循环
      eventType = parser.next(); } } catch (XmlPullParserException e) { // TODO Auto-generated catch block e.printStackTrace(); } return list; } }
     

    三、DOM解析

      “文档对象模型”方式,解析完的Xml将生成一个树状结构的对象。

      1、DOM解析相对前两种比较麻烦,代码如下:

      

    import java.io.InputStream;
    import java.util.ArrayList;
    import java.util.List;
    
    import javax.xml.parsers.DocumentBuilder;
    import javax.xml.parsers.DocumentBuilderFactory;
    
    import org.w3c.dom.Document;
    import org.w3c.dom.Element;
    import org.w3c.dom.Node;
    import org.w3c.dom.NodeList;
    
    import com.xml.httputils.http_post;
    
    public class DomService {
    
        public DomService() {
        }
    
        public static List<Person> parseXML(InputStream is) throws Exception {
            List<Person> list = new ArrayList<Person>();
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            DocumentBuilder builder = factory.newDocumentBuilder();
            Document document = builder.parse(is);
            // 获得节点
            Element element = document.getDocumentElement();
            NodeList nodeList = element.getElementsByTagName("person");
            for (int i = 0; i < nodeList.getLength(); i++) {
                Element personElement = (Element) nodeList.item(i);
                Person p = new Person();
                p.setId(personElement.getAttribute("id"));
                NodeList personList = personElement.getChildNodes();
                for (int j = 0; j < personList.getLength(); j++) {
                    if (personList.item(j).getNodeType() == Node.ELEMENT_NODE) {
                        if ("name".equals(personList.item(j).getNodeName())) {
                            p.setName(personList.item(j).getFirstChild()
                                    .getNodeValue());
                        } else if ("age".equals(personList.item(j).getNodeName())) {
                            p.setAge(personList.item(j).getFirstChild()
                                    .getNodeValue());
                        }
                    }
                }
                list.add(p);
            }
            return list;
    
        }
    
        public static void main(String[] args) throws Exception {
            DomService dom = new DomService();
            List<Person> ps = dom.parseXML(http_post.getXMLStream());
            for (Person p : ps) {
                System.out.println(p);
            }
        }
    }

    总结:

      对于小内存的设备,尤其是Android设备,使用PULL解析或者SAX解析远优于DOM解析。

  • 相关阅读:
    Python使用asyncio+aiohttp异步爬取猫眼电影专业版
    Django
    Django
    Vue 1-- ES6 快速入门、vue的基本语法、vue应用示例,vue基础语法
    Django
    Django
    Django
    Django
    django--权限(1)初识
    Django
  • 原文地址:https://www.cnblogs.com/dennisac/p/3504828.html
Copyright © 2011-2022 走看看