【Android学习】JSON与XML综合六种解析方式-综合案例

来源:互联网 发布:兴义农村淘宝招聘 编辑:程序博客网 时间:2024/06/05 11:55


概述:


项目包含Android端+Web后台端,使用到了Handler ,多线程, Apache Http编程 ,XML+JSON文件的6种解析方式,是个不错的学习案例。


JAR包和项目下载地址在最后面。


1、Web端

 1、JSON字符串

2、XML文件


2、Android端


一、什么是JSON?

JSON是一种取代XML的数据结构,和xml相比,它更小巧但描述能力却不差,由于它的小巧所以网络传输数据将减少更多流量从而加快速度。

JSON就是一串字符串 只不过元素会使用特定的符号标注。

{} 双括号表示对象

[] 中括号表示数组

"" 双引号内是属性或值

: 冒号表示后者是前者的值(这个值可以是字符串、数字、也可以是另一个数组或对象)

所以 {"name": "Michael"} 可以理解为是一个包含name为Michael的对象

而[{"name": "Michael"},{"name": "Jerry"}]就表示包含两个对象的数组

当然了,你也可以使用{"name":["Michael","Jerry"]}来简化上面一部,这是一个拥有一个name数组的对象

二、传统的JSON

1、生成JSON字符串

[java] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. <span style="font-size:14px;">public static String createJsonString(String key, Object value) {  
  2.         JSONObject jsonObject = new JSONObject();  
  3.         jsonObject.put(key, value);  
  4.         return jsonObject.toString();  
  5.     }</span>  

2、解析JSON字符串

分为以下三种情况,一个JavaBean,一个List数组,一个嵌套Map的List数组:
[java] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. <span style="font-size:14px;">import java.util.ArrayList;  
  2. import java.util.HashMap;  
  3. import java.util.Iterator;  
  4. import java.util.List;  
  5. import java.util.Map;  
  6.   
  7. import org.json.JSONArray;  
  8. import org.json.JSONObject;  
  9.   
  10. import com.android.myjson.domain.Person;  
  11.   
  12. /** 
  13.  * 完成对json数据的解析 
  14.  *  
  15.  */  
  16. public class JsonTools {  
  17.   
  18.   
  19.     public static Person getPerson(String key, String jsonString) {  
  20.         Person person = new Person();  
  21.         try {  
  22.             JSONObject jsonObject = new JSONObject(jsonString);  
  23.             JSONObject personObject = jsonObject.getJSONObject("person");  
  24.             person.setId(personObject.getInt("id"));  
  25.             person.setName(personObject.getString("name"));  
  26.             person.setAddress(personObject.getString("address"));  
  27.         } catch (Exception e) {  
  28.             // TODO: handle exception  
  29.         }  
  30.         return person;  
  31.     }  
  32.   
  33.     public static List<Person> getPersons(String key, String jsonString) {  
  34.         List<Person> list = new ArrayList<Person>();  
  35.         try {  
  36.             JSONObject jsonObject = new JSONObject(jsonString);  
  37.             // 返回json的数组  
  38.             JSONArray jsonArray = jsonObject.getJSONArray(key);  
  39.             for (int i = 0; i < jsonArray.length(); i++) {  
  40.                 JSONObject jsonObject2 = jsonArray.getJSONObject(i);  
  41.                 Person person = new Person();  
  42.                 person.setId(jsonObject2.getInt("id"));  
  43.                 person.setName(jsonObject2.getString("name"));  
  44.                 person.setAddress(jsonObject2.getString("address"));  
  45.                 list.add(person);  
  46.             }  
  47.         } catch (Exception e) {  
  48.             // TODO: handle exception  
  49.         }  
  50.         return list;  
  51.     }  
  52.   
  53.     public static List<String> getList(String key, String jsonString) {  
  54.         List<String> list = new ArrayList<String>();  
  55.         try {  
  56.             JSONObject jsonObject = new JSONObject(jsonString);  
  57.             JSONArray jsonArray = jsonObject.getJSONArray(key);  
  58.             for (int i = 0; i < jsonArray.length(); i++) {  
  59.                 String msg = jsonArray.getString(i);  
  60.                 list.add(msg);  
  61.             }  
  62.         } catch (Exception e) {  
  63.             // TODO: handle exception  
  64.         }  
  65.         return list;  
  66.     }  
  67.   
  68.     public static List<Map<String, Object>> listKeyMaps(String key,  
  69.             String jsonString) {  
  70.         List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();  
  71.         try {  
  72.             JSONObject jsonObject = new JSONObject(jsonString);  
  73.             JSONArray jsonArray = jsonObject.getJSONArray(key);  
  74.             for (int i = 0; i < jsonArray.length(); i++) {  
  75.                 JSONObject jsonObject2 = jsonArray.getJSONObject(i);  
  76.                 Map<String, Object> map = new HashMap<String, Object>();  
  77.                 Iterator<String> iterator = jsonObject2.keys();  
  78.                 while (iterator.hasNext()) {  
  79.                     String json_key = iterator.next();  
  80.                     Object json_value = jsonObject2.get(json_key);  
  81.                     if (json_value == null) {  
  82.                         json_value = "";  
  83.                     }  
  84.                     map.put(json_key, json_value);  
  85.                 }  
  86.                 list.add(map);  
  87.             }  
  88.         } catch (Exception e) {  
  89.             // TODO: handle exception  
  90.         }  
  91.         return list;  
  92.     }  
  93. }</span>  

三、GSON

1、生成JSON字符串

[java] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. <span style="font-size:14px;">import com.google.gson.Gson;  
  2.   
  3. public class JsonUtils {  
  4.   
  5.     public static String createJsonObject(Object obj) {  
  6.         Gson gson = new Gson();  
  7.         String str = gson.toJson(obj);  
  8.         return str;  
  9.   
  10.     }  
  11. }</span>  

二、解析JSON

[java] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. <span style="font-size:14px;">import java.util.ArrayList;  
  2. import java.util.List;  
  3. import java.util.Map;  
  4.   
  5. import com.google.gson.Gson;  
  6. import com.google.gson.reflect.TypeToken;  
  7.   
  8. ;  
  9. public class GsonTools {  
  10.   
  11.     public GsonTools() {  
  12.         // TODO Auto-generated constructor stub  
  13.     }  
  14.   
  15.     /** 
  16.      * @param <T> 
  17.      * @param jsonString 
  18.      * @param cls 
  19.      * @return 
  20.      */  
  21.     public static <T> T getPerson(String jsonString, Class<T> cls) {  
  22.         T t = null;  
  23.         try {  
  24.             Gson gson = new Gson();  
  25.             t = gson.fromJson(jsonString, cls);  
  26.         } catch (Exception e) {  
  27.             // TODO: handle exception  
  28.         }  
  29.         return t;  
  30.     }  
  31.   
  32.     /** 
  33.      * 使用Gson进行解析 List<Person> 
  34.      *  
  35.      * @param <T> 
  36.      * @param jsonString 
  37.      * @param cls 
  38.      * @return 
  39.      */  
  40.     public static <T> List<T> getPersons(String jsonString, Class<T> cls) {  
  41.         List<T> list = new ArrayList<T>();  
  42.         try {  
  43.             Gson gson = new Gson();  
  44.             list = gson.fromJson(jsonString, new TypeToken<List<Person.class>>() {  
  45.             }.getType());  
  46.         } catch (Exception e) {  
  47.         }  
  48.         return list;  
  49.     }  
  50.   
  51.     /** 
  52.      * @param jsonString 
  53.      * @return 
  54.      */  
  55.     public static List<String> getList(String jsonString) {  
  56.         List<String> list = new ArrayList<String>();  
  57.         try {  
  58.             Gson gson = new Gson();  
  59.             list = gson.fromJson(jsonString, new TypeToken<List<String>>() {  
  60.             }.getType());  
  61.         } catch (Exception e) {  
  62.             // TODO: handle exception  
  63.         }  
  64.         return list;  
  65.     }  
  66.   
  67.     public static List<Map<String, Object>> listKeyMaps(String jsonString) {  
  68.         List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();  
  69.         try {  
  70.             Gson gson = new Gson();  
  71.             list = gson.fromJson(jsonString,  
  72.                     new TypeToken<List<Map<String, Object>>>() {  
  73.                     }.getType());  
  74.         } catch (Exception e) {  
  75.             // TODO: handle exception  
  76.         }  
  77.         return list;  
  78.     }  
  79. }</span>  


四、FastJSON

[java] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. <span style="font-size:14px;">import java.util.ArrayList;  
  2. import java.util.List;  
  3. import java.util.Map;  
  4.   
  5. import com.alibaba.fastjson.JSON;  
  6. import com.alibaba.fastjson.TypeReference;  
  7.   
  8. public class JsonTool {  
  9.   
  10.     public static <T> T getPerson(String jsonstring, Class<T> cls) {  
  11.         T t = null;  
  12.         try {  
  13.             t = JSON.parseObject(jsonstring, cls);  
  14.         } catch (Exception e) {  
  15.             // TODO: handle exception  
  16.         }  
  17.         return t;  
  18.     }  
  19.   
  20.     public static <T> List<T> getPersonList(String jsonstring, Class<T> cls) {  
  21.         List<T> list = new ArrayList<T>();  
  22.         try {  
  23.             list = JSON.parseArray(jsonstring, cls);  
  24.         } catch (Exception e) {  
  25.             // TODO: handle exception  
  26.         }  
  27.         return list;  
  28.     }  
  29.   
  30.     public static <T> List<Map<String, Object>> getPersonListMap1(  
  31.             String jsonstring) {  
  32.         List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();  
  33.         try {  
  34.             list = JSON.parseObject(jsonstring,  
  35.                     new TypeReference<List<Map<String, Object>>>() {  
  36.                     }.getType());  
  37.   
  38.         } catch (Exception e) {  
  39.             // TODO: handle exception  
  40.         }  
  41.   
  42.         return list;  
  43.     }  
  44. }</span>  

总结:

JSON对于移动设备来说,尤其对于网络环境较差和流量限制的情况下,相对于XML格式的数据传输会更节省流量,传输效率更高。在这三种解析方式中FastJson是效率最高的,推荐使用。





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("\n")) {                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解析容易

   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解析。

0 0