美文网首页
解析数据

解析数据

作者: 爱做梦的严重精神病患者 | 来源:发表于2018-10-28 23:04 被阅读0次

    1.XML格式数据解析

    XML格式数据:
    <apps>
      <app>
        <id>1</id>
        <name>Google Maps</name>
        <version>1.0</version>
      </app>
      <app>...</app>
    </apps>

    • Pull解析:

     首先,利用工厂方法获得XmlPullParser实例对象。

    XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
    XmlPullParser xmlPullParser = factory.newPullParser();
    

     接下来,将服务器返回的数据传入获得XML数据的相关信息(eventType)。

    //设置输入流
    xmlPullParser.setInput(new StringReader(xmlData));
    //获得当前的解析事件
    int eventType = xmlPullParser.getEventType();
    

     根据当前解析事件的类型进行循环读取、解析

    while(eventType != XmlPullParser.END_DOCUMENT) {
         String nodeName = xmlPullParser.getName();
         switch(eventType) {
          //开始解析节点
          case XmlPullParser.START_TAG: {
             if("id".equals(nodeName)) {
                id = xmlPullParser.nextText();
                } else if ("name".equals(nodeName)) {
                name = xmlPullParser.nextText();
                } else if ("version".equals(nodeName)) {
                version = xmlPullParser.nextText();
                }
                break;
           }
           //完成解析某个节点
           case XmlPullParser.END_TAG:{
             if ("app".equals(nodeName)) {
             //输出信息
                  Log.d("MainActivity","id is " + id);
                  Log.d("MainActivity","name is " + name);
                  Log.d("MainActivity","version is " + version);
              }
              break;
            }
            default :
                  break;
          }
          //获取下一个解析事件 
          eventType = xmlPullParser.next();
    }
    
    • SAX解析
       首先,新建一个类继承DefaulfHandler,并重写父类的5个方法
       每当开始解析某个节点的时候,startElement()方法就会得到调用,其中localName参数记录着当前节点的名字
       接着在解析节点中具体内容的时候就会调用characters()方法,根据当前节点名(在startElement()方法中获得)进行判断,将解析出的内容添加到对应的StringBuilder对象中。
      最后endElement()方法中进行判断,如果app节点已经解析完成,就打印出id、name和version的内容,并清空StringBuilder
    public class MyHandler extends DefaultHandler {
        private String nodeName;
        private StringBuilder id;
        private StringBuilder name;
        private StringBuilder version;
    
    
        /**
         * 在开始XML解析时调用
         * @throws SAXException
         */
        @Override
        public void startDocument() throws SAXException {
           id = new StringBuilder();
           name = new StringBuilder();
           version = new StringBuilder();
        }
    
        /**
         * 在完成整个XML解析时调用
         * @throws SAXException
         */
        @Override
        public void endDocument() throws SAXException {
            super.endDocument();
        }
    
        /**
         * 在开始解析某个节点时调用
         * @param uri
         * @param localName
         * @param qName
         * @param attributes
         * @throws SAXException
         */
        @Override
        public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
            //记录当前节点名
            nodeName = localName;
        }
    
        /**
         * 在完成解析某个节点时调用
         * @param uri
         * @param localName
         * @param qName
         * @throws SAXException
         */
        @Override
        public void endElement(String uri, String localName, String qName) throws SAXException {
           if ("app".equals(localName)) {
               Log.d("MyHandler", "id is " + id.toString().trim());
               Log.d("MyHandler", "name is " + name.toString().trim());
               Log.d("MyHandler", "version is " + version.toString().trim());
               //将StringBuilder清空
               id.setLength(0);
               name.setLength(0);
               version.setLength(0);
           }
        }
    
        /**
         * 获取节点中间内容的时候调用
         * @param ch
         * @param start
         * @param length
         * @throws SAXException
         */
        @Override
        public void characters(char[] ch, int start, int length) throws SAXException {
            //根据当前的节点名判断将内容添加到哪一个StringBuilder对象中
            if ("id".equals(nodeName)) {
                id.append(ch, start, length);
            } else if ("name".equals(nodeName)) {
                name.append(ch, start, length);
            } else if ("version".equals(nodeName)) {
                version.append(ch, start, length);
            }
        }
    }
    

     父类的方法重写完毕后调用工厂方法构建XMLReader的实例对象,将MyHandler的实例设置到XMLReader中。

            SAXParserFactory factory = SAXParserFactory.newInstance();
            XMLReader xmlReader = factory.newSAXParser().getXMLReader();
            MyHandler myHandler = new MyHandler();
            //将MyHandler的实例设置到XMLReader中
            xmlReader.setContentHandler(myHandler);
            //构建输入流,开始解析,数据在MyHandler中进行处理
            xmlReader.parse(new InputSource(new StringReader(xmlData)));
    

    2.JSON格式数据解析

    JSON具有体积小的优势,在数据传输中会经常被使用。

    JSON格式:
     [{"id":"5","version":"5.5","name":"Clash of Clans"},
     {"id":"6","version":"7.0","name":"Boom Beach"},
     {"id":"7","version":"3.5","name":"Clash Royale"}]

    解析JSON数据的方法有很多种,这里主要介绍JSONObjectGSON

    • JSONObject

     在介绍JSONObject之前,需要介绍一个JSONArray的概念。以上面的JSON格式的数据为例,"{ }"内的信息为一个JSONObject"[ ]"内的信息是由3个JSONObject组成的一个JSONArray
     当返回的数据格式是JSONArray时,循环遍历这个JSONArray从中取出每一个元素都是一个JSONObject对象每个JSONObject对象包含所需要的信息

    //当返回信息的格式为JSONArray
      JSONArray jsonArray = new JSONArray(jsonData);
            for (int i = 0; i < jsonArray.length(); i++) {
                JSONObject jsonObject = jsonArray.getJSONObject(i);
                String id = jsonObject.getString("id");
                String name = jsonObject.getString("name");
                String version = jsonObject.getString("version");
            }
    //当返回信息格式为JSONObject
     JSONObject jsonObject = new JSONObject(jsonData);
                String id = jsonObject.getString("id");
                String name = jsonObject.getString("name");
                String version = jsonObject.getString("version");
    
    • GSON
       使用GSON从服务器获取数据,需要建立相应的JavaBean形成相应的映射
    public class App {
        //JavaBean的属性名称需要与想要获取的JSON格式中的数据名称保持一致
        private String id;//"id"
        private String name;
        private String version;
    
        public String getId() {
            return id;
        }
    
        public void setId(String id) {
            this.id = id;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public String getVersion() {
            return version;
        }
    
        public void setVersion(String version) {
            this.version = version;
        }
    }
    

     当返回的数据是JSONObject时:

        Gson gson = new Gson();
        App app = gson.fromJson(jsonData, App.class);
    

     当返回的数据是JSONArray时,需要借助TypeToken类(需要匿名类来调构造函数)期望解析成的数据类型传入fromJson()方法中:

        Gson gson = new Gson();
        List<App> appList = gson.fromJson(jsonData,
                                  //利用TypeToken的匿名类来构建实例
                                  new TypeToken<List<App>>(){ }.getType());
        for(App app : appList) {
              Log.d("TAG", "id is " + app.getId());
              Log.d("TAG", "name is " + app.getName());
              Log.d("TAG", "version is " + app.getVersion());
    
        }
    

    相关文章

      网友评论

          本文标题:解析数据

          本文链接:https://www.haomeiwen.com/subject/kvzptqtx.html