现在的位置: 首页 > 综合 > 正文

【Android学习】JSON与XML综合六种解析方式-综合案例(web项目源码+android源码+jar包)

2018年02月17日 ⁄ 综合 ⁄ 共 10751字 ⁄ 字号 评论关闭

概述:


项目包含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字符串

<span style="font-size:14px;">public static String createJsonString(String key, Object value) {
		JSONObject jsonObject = new JSONObject();
		jsonObject.put(key, value);
		return jsonObject.toString();
	}</span>

2、解析JSON字符串

分为以下三种情况,一个JavaBean,一个List数组,一个嵌套Map的List数组:
<span style="font-size:14px;">import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.json.JSONArray;
import org.json.JSONObject;

import com.android.myjson.domain.Person;

/**
 * 完成对json数据的解析
 * 
 */
public class JsonTools {


	public static Person getPerson(String key, String jsonString) {
		Person person = new Person();
		try {
			JSONObject jsonObject = new JSONObject(jsonString);
			JSONObject personObject = jsonObject.getJSONObject("person");
			person.setId(personObject.getInt("id"));
			person.setName(personObject.getString("name"));
			person.setAddress(personObject.getString("address"));
		} catch (Exception e) {
			// TODO: handle exception
		}
		return person;
	}

	public static List<Person> getPersons(String key, String jsonString) {
		List<Person> list = new ArrayList<Person>();
		try {
			JSONObject jsonObject = new JSONObject(jsonString);
			// 返回json的数组
			JSONArray jsonArray = jsonObject.getJSONArray(key);
			for (int i = 0; i < jsonArray.length(); i++) {
				JSONObject jsonObject2 = jsonArray.getJSONObject(i);
				Person person = new Person();
				person.setId(jsonObject2.getInt("id"));
				person.setName(jsonObject2.getString("name"));
				person.setAddress(jsonObject2.getString("address"));
				list.add(person);
			}
		} catch (Exception e) {
			// TODO: handle exception
		}
		return list;
	}

	public static List<String> getList(String key, String jsonString) {
		List<String> list = new ArrayList<String>();
		try {
			JSONObject jsonObject = new JSONObject(jsonString);
			JSONArray jsonArray = jsonObject.getJSONArray(key);
			for (int i = 0; i < jsonArray.length(); i++) {
				String msg = jsonArray.getString(i);
				list.add(msg);
			}
		} catch (Exception e) {
			// TODO: handle exception
		}
		return list;
	}

	public static List<Map<String, Object>> listKeyMaps(String key,
			String jsonString) {
		List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
		try {
			JSONObject jsonObject = new JSONObject(jsonString);
			JSONArray jsonArray = jsonObject.getJSONArray(key);
			for (int i = 0; i < jsonArray.length(); i++) {
				JSONObject jsonObject2 = jsonArray.getJSONObject(i);
				Map<String, Object> map = new HashMap<String, Object>();
				Iterator<String> iterator = jsonObject2.keys();
				while (iterator.hasNext()) {
					String json_key = iterator.next();
					Object json_value = jsonObject2.get(json_key);
					if (json_value == null) {
						json_value = "";
					}
					map.put(json_key, json_value);
				}
				list.add(map);
			}
		} catch (Exception e) {
			// TODO: handle exception
		}
		return list;
	}
}</span>

三、GSON

1、生成JSON字符串

<span style="font-size:14px;">import com.google.gson.Gson;

public class JsonUtils {

	public static String createJsonObject(Object obj) {
		Gson gson = new Gson();
		String str = gson.toJson(obj);
		return str;

	}
}</span>

二、解析JSON

<span style="font-size:14px;">import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

;
public class GsonTools {

	public GsonTools() {
		// TODO Auto-generated constructor stub
	}

	/**
	 * @param <T>
	 * @param jsonString
	 * @param cls
	 * @return
	 */
	public static <T> T getPerson(String jsonString, Class<T> cls) {
		T t = null;
		try {
			Gson gson = new Gson();
			t = gson.fromJson(jsonString, cls);
		} catch (Exception e) {
			// TODO: handle exception
		}
		return t;
	}

	/**
	 * 使用Gson进行解析 List<Person>
	 * 
	 * @param <T>
	 * @param jsonString
	 * @param cls
	 * @return
	 */
	public static <T> List<T> getPersons(String jsonString, Class<T> cls) {
		List<T> list = new ArrayList<T>();
		try {
			Gson gson = new Gson();
			list = gson.fromJson(jsonString, new TypeToken<List<Person.class>>() {
			}.getType());
		} catch (Exception e) {
		}
		return list;
	}

	/**
	 * @param jsonString
	 * @return
	 */
	public static List<String> getList(String jsonString) {
		List<String> list = new ArrayList<String>();
		try {
			Gson gson = new Gson();
			list = gson.fromJson(jsonString, new TypeToken<List<String>>() {
			}.getType());
		} catch (Exception e) {
			// TODO: handle exception
		}
		return list;
	}

	public static List<Map<String, Object>> listKeyMaps(String jsonString) {
		List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
		try {
			Gson gson = new Gson();
			list = gson.fromJson(jsonString,
					new TypeToken<List<Map<String, Object>>>() {
					}.getType());
		} catch (Exception e) {
			// TODO: handle exception
		}
		return list;
	}
}</span>

四、FastJSON

<span style="font-size:14px;">import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;

public class JsonTool {

	public static <T> T getPerson(String jsonstring, Class<T> cls) {
		T t = null;
		try {
			t = JSON.parseObject(jsonstring, cls);
		} catch (Exception e) {
			// TODO: handle exception
		}
		return t;
	}

	public static <T> List<T> getPersonList(String jsonstring, Class<T> cls) {
		List<T> list = new ArrayList<T>();
		try {
			list = JSON.parseArray(jsonstring, cls);
		} catch (Exception e) {
			// TODO: handle exception
		}
		return list;
	}

	public static <T> List<Map<String, Object>> getPersonListMap1(
			String jsonstring) {
		List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
		try {
			list = JSON.parseObject(jsonstring,
					new TypeReference<List<Map<String, Object>>>() {
					}.getType());

		} catch (Exception e) {
			// TODO: handle exception
		}

		return list;
	}
}</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解析。

项目下载地址:http://pan.baidu.com/s/1ntukDDJ
CSDN下载地址:客户端 服务端

抱歉!评论已关闭.