A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

   在网络上传输数据时最常用的格式有两种:XML和JSON,下面就来学习如何解析XML和JSON格式的数据。

一、解析XML格式数据


    XML格式内容如下:

<apps>
    <app>
        <id>1</id>
        <name>Google Maps</name>
        <version>1.0</version>
    </app>
    <app>
        <id>2</id>
        <name>Chrome</name>
        <version>2.1</version>
    </app>
    <app>
        <id>3</id>
        <name>Google Play</name>
        <version>2.3</version>
    </app>
</apps>

1.1 Pull方式解析

    解析XML格式的数据方法有很多,常用的两种是Pull解析和SAX解析。Pull解析方法如下:



  •     private void parseXMLWithPull(String xmlData) {



  •         try {



  •             final XmlPullParserFactory factory = XmlPullParserFactory.newInstance();



  •             final XmlPullParser xmlPullParser = factory.newPullParser();



  •             xmlPullParser.setInput(new StringReader(xmlData));



  •             int eventType = xmlPullParser.getEventType();



  •             String id = "", name = "", version = "";



  •             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();



  •             }



  •         }



  •         catch (Exception e) {



  •             e.printStackTrace();



  •         }



  •     }


    首先通过XmlPullParserFactory的实例获得到XmlPullPaser对象,然后调用XmlPullParser的setInput()方法将服务器返回的XML数据设置进去就可以开始解析了。解析过程也非常简单,通过getEventType()方法可以得到当前的解析事件,然后在体格while循环中不断进行解析,如果当前的解析事件不等于XmlPullParser.END_DOCUMENT,说明解析工作还没有完成,调用next()方法可以获取下一个解析事件。

    在while循环中,通过getName()方法得到当前节点的名字,如果发现节点名等于id、name或version,就调用nextText()方法来获取节点的具体内容,每当解析完成一个app节点后就将获取到的内容打印出来。

1.2 SAX方式解析

    使用SAX方式解析,通常情况下,会新建一个类继承自DefaultHandler,并重写父类的五个方法,如下所示:



  • public class SAXHandler extends DefaultHandler {







  •     private String nodeName;







  •     private StringBuilder id;



  •     private StringBuilder name;



  •     private StringBuilder version;







  •     @Override



  •     public void startDocument() throws SAXException {



  •         //super.startDocument();



  •         id = new StringBuilder();



  •         name = new StringBuilder();



  •         version = new StringBuilder();



  •     }







  •     @Override



  •     public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {



  •         //super.startElement(uri, localName, qName, attributes);



  •         // 记录当前节点名



  •         nodeName = localName;



  •     }







  •     @Override



  •     public void characters(char[] ch, int start, int length) throws SAXException {



  •         //super.characters(ch, start, length);



  •         // 根据节点名判断将内容添加到哪一个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);



  •         }



  •     }







  •     @Override



  •     public void endElement(String uri, String localName, String qName) throws SAXException {



  •         //super.endElement(uri, localName, qName);



  •         if ("app".equals(localName)) {



  •             Log.d("MainActivity", "id is " + id.toString().trim());



  •             Log.d("MainActivity", "name is " + name.toString().trim());



  •             Log.d("MainActivity", "version is " + version.toString().trim());



  •         }



  •         // 最后要将StringBuilder清空掉



  •         id.setLength(0);



  •         name.setLength(0);



  •         version.setLength(0);



  •     }







  •     @Override



  •     public void endDocument() throws SAXException {



  •         super.endDocument();



  •     }



  • }


    接下来修改MainActivity中的代码,如下所示:


  •     private void parseXMLWithSAX(String xmlData){



  •         try



  •         {



  •             final SAXParserFactory factory = SAXParserFactory.newInstance();



  •             final XMLReader xmlReader = factory.newSAXParser().getXMLReader();



  •             final SAXHandler handler = new SAXHandler();



  •             // 将SAXHandler的实例设置到XMLReader中



  •             xmlReader.setContentHandler(handler);



  •             // 开始解析执行



  •             xmlReader.parse(new InputSource(new StringReader(xmlData)));



  •         }



  •         catch (Exception e)



  •         {



  •             e.printStackTrace();



  •         }



  •     }


二、解析JSON格式数据

    比起XML格式,JSON格式的主要优势在于它的体积更小,在网络上传输的时候可以更省流量。但缺点在于,它的语义性较差,看起来不如XML直观。

    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"}]

2.1 使用JSONObject

    类似地,解析JSON数据也有很多方法,可以使用官方提供的JSONObject,也可以使用谷歌的开源库GSON。JSONObject解析方法如下:



  •     private void parseJSONWithJSONObject(String jsonData) {



  •         try {



  •             final JSONArray jsonArray = new JSONArray(jsonData);



  •             for (int i = 0; i < jsonArray.length(); i++) {



  •                 final JSONObject jsonObject = jsonArray.getJSONObject(i);



  •                 String id = jsonObject.getString("id");



  •                 String name = jsonObject.getString("name");



  •                 String version = jsonObject.getString("version");



  •                 Log.d("MainActivity", "id is " + id);



  •                 Log.d("MainActivity", "name is " + name);



  •                 Log.d("MainActivity", "version is " + version);



  •             }



  •         }



  •         catch (JSONException e) {



  •             e.printStackTrace();



  •         }



  •     }


    很容易看出,解析JSON的代码真的非常简单,首先将服务器返回的数据传入到一个JSONArray对象中。然后遍历这个JSONArray,从中取出每一个元素都是JSONObject的对象,只需要调用getString()方法就可以将这些数据取出。

2.2 使用GSON

    想要使用GSON,必须先添加GSON库的依赖,编辑app/build.gradle文件,在dependencies闭包中添加如下内容:

compile 'com.google.code.gson:gosn:2.7'

    GSON可以将一段JSON格式的字符串自动映射成一个对象,从而不需要我们再手动去编写代码进行解析了。

    首先新建App类,并加入id、name和version这3个字段,如下所示:



  • public class App {







  •     private String 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;



  •     }



  • }


    修改MainActivy中的代码,如下所示:


  •     private void parseJSONWithGSON(String jsonData) {



  •         final Gson gson = new Gson();



  •         List<App> appList = gson.fromJson(jsonData, new TypeToken<List<App>>() {}.getType());



  •         for (App app : appList) {



  •             Log.d("MainActivity", "id is " + app.getId());



  •             Log.d("MainActivity", "name is " + app.getName());



  •             Log.d("MainActivity", "version is " + app.getVersion());



  •         }




0 个回复

您需要登录后才可以回帖 登录 | 加入黑马