Android学习笔记-XML解析和JSON

XML解析

一、SAX(Simple API for XML)

SAX解析器是一种基于事件的解析器,核心是事件处理模式,主要是围绕着事件源以及事件处理器来工作的。当事件源产生事件后,调用事件处理器相应的处理方法。在事件源调用事件处理器中特定的方法的时候,还要传递给事件处理器相应事件的状态信息,这样事件处理器才能够根据提供的时间信息来决定自己的行为。
优点:解析速度快,占用内存少。适合在Android移动设备中使用。

二、DOM

DOM是基于树形结构的节点或信息片段的集合,允许开发人员使用DOM API遍历XML树、检索所需数据。分析该结构通常需要加载整个文档和构造树形结构,然后才检索和更新节点信息。效率高,对于大文档,消耗资源过多。

三、PULL

类似SAX,都是基于事件的模式。不同的是,需要自己产生事件然后做相应的操作,而不像SAX由处理器触发一种事件的方法。PULL小巧轻便,解析速度快,简单易用,一般使用在Android中。

demo:
读取Android Project中位于assert文件夹下的books.xml文件:
<?xml version="1.0" encoding="UTF-8" ?>
<books>
	<book no="1001">
	    <name>java高级编程</name>
	    <price>99.00</price>
	</book>    
	<book no="1002">
	    <name>java设计模式</name>
	    <price>120.00</price>
	</book>    
</books>

SAX

编写一个SAXHandler事件处理类,继承DefaultHandler,重写需要使用的方法
package com.edu.util;

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 SaxHandler extends DefaultHandler {

	private List<HashMap<String, String>> list;
	private String tagName;
	//保存节点对应的数据
	private HashMap<String, String> item;
	
	/*
	 * 文档开始
	 */
	@Override
	public void startDocument() throws SAXException {
		list = new ArrayList<>();
	}

	/*
	 * 文档结束 
	 */
	@Override
	public void endDocument() throws SAXException {
	}

	@Override
	public void startElement(String uri, String localName, String qName,
			Attributes attributes) throws SAXException {
		if(!localName.equals("books")){
			if(localName.equals("book")){
				item = new HashMap<>();
				//获取book节点的值
				String no = attributes.getValue("no");
				item.put("no", no);
			}else{
				tagName = localName;
			}
		}
	}

	@Override
	public void endElement(String uri, String localName, String qName)
			throws SAXException {
		//判断是否需要把item添加到list中
		if(localName.equals("book")){
			list.add(item);
			item = null;
		}
		tagName = null;
	}

	@Override
	public void characters(char[] ch, int start, int length)
			throws SAXException {
		//判断item是否为空,因为空文本节点也进入该方法
		if(item != null && tagName != null){
			String str = new String(ch, start, length);
			item.put(tagName, str);
		}
	}

	/**
	 * @return XML数据
	 */
	public List<HashMap<String, String>> getData(){
		return list;
	}
	
}
SAX工具类:
package com.edu.util;

import java.io.InputStream;
import java.util.HashMap;
import java.util.List;

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

public class SaxUtil {

	public static List<HashMap<String, String>> readXml(InputStream is)
			throws Exception{
		List<HashMap<String, String>> list = null;
		//获取SAX转换器的工厂
		SAXParserFactory factory = SAXParserFactory.newInstance();
		//获取SAX转换器
		SAXParser parser = factory.newSAXParser();
		//构建事件处理程序
		SaxHandler saxHandler = new SaxHandler();
		//设置程序处理xml文件
		parser.parse(is, saxHandler);
		list = saxHandler.getData();
		//关闭输入流
		is.close();
		return list;
	}
	
}

DOM

DOM工具类:
package com.edu.util;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
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;

public class DomUtil {

	public static List<HashMap<String, String>> readXml(InputStream is)
			throws Exception{
		List<HashMap<String, String>> list = new ArrayList<>();
		//创建工厂
		DocumentBuilderFactory factory =
				DocumentBuilderFactory.newInstance();
		//建造器
		DocumentBuilder builder = factory.newDocumentBuilder();
		//通过输入流生成文档对象
		Document doc = builder.parse(is);
		//获取文档的根节点
//		Element root = doc.getDocumentElement();
		//方法一:通过根节点,查找子节点
//		NodeList nodeList = root.getElementsByTagName("book");
		//推荐->方法二:获取所有book节点,包括不在同一等级节点
		NodeList nodeList = doc.getElementsByTagName("book");
		HashMap<String, String> item = null;
		//循环遍历所有节点
		for(int i = 0; i < nodeList.getLength(); i++){
			item = new HashMap<>();
			//获取第i+1个book节点
			Element eleBook = (Element) nodeList.item(i);
			String no = eleBook.getAttribute("no");
			item.put("no", no);
			//获取book节点下的子节点
			NodeList childs = eleBook.getChildNodes();
			//遍历所有子节点
			for(int j = 0; j < childs.getLength(); j++){
				//判断当前节点是否为元素节点
				if(childs.item(j).getNodeType()==Node.ELEMENT_NODE){
					Element ele = (Element) childs.item(j);
					String name = ele.getNodeName();
					//获取第一个字节点的值
					String value = ele.getFirstChild().getNodeValue();
					item.put(name, value);
				}
			}
			list.add(item);
		}
		return list;
	}
	
}

PULL

PULL工具类
package com.edu.util;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import org.xmlpull.v1.XmlPullParser;

import android.util.Xml;

public class PullUtil {

	public static List<HashMap<String, String>> readXml(InputStream is)
			throws Exception{
		List<HashMap<String, String>> list = new ArrayList<>();
		XmlPullParser pull = Xml.newPullParser();
		//设置编码
		pull.setInput(is, "UTF-8");
		//获取处理事件的类型
		int type = pull.getEventType();
		HashMap<String, String> item = null;
		//如果类型不等于文档结束
		while(type != XmlPullParser.END_DOCUMENT){
			switch (type) {
			//文档开始
			case XmlPullParser.START_TAG:
				//判断节点名称
				if("book".equals(pull.getName())){
					item = new HashMap<>();
					for(int i = 0; i < pull.getAttributeCount(); i++){
						String name = pull.getAttributeName(i);
						String value = pull.getAttributeValue(i);
						item.put(name, value);
					}
				}else if("name".equals(pull.getName())){
					//文本节点
					item.put("name", pull.nextText());
				}else if("price".equals(pull.getName())){
					//文本节点
					item.put("price", pull.nextText());
				}
				break;
			case XmlPullParser.END_TAG:
				//节点结束
				if("book".equals(pull.getName())){
					list.add(item);
					item = null;
				}
				break;
			}
			//下一节点
			type = pull.next();
		}
		return list;
	}	
}
在MainActivity中进行方法测试:
	public void saxRead(View view){
		//转换成文件流
		try {
			InputStream is = getAssets().open("books.xml");
			System.out.println("SAX->"+SaxUtil.readXml(is));
			is.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public void domRead(View view){
		try {
			InputStream is = getAssets().open("books.xml");
			System.out.println("DOM->"+DomUtil.readXml(is));
			is.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public void pullRead(View view){
		try {
			InputStream is = getAssets().open("books.xml");
			System.out.println("PULL->"+PullUtil.readXml(is));
			is.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
测试效果:
Android学习笔记-XML解析和JSON_第1张图片

JSON

不管在服务器端生成或处理XML,还是在客户端用JavaScript解析XML,开发效率都很低。
JSON可以传输String,Number,Boolean,数组,或者一个Object对象
语法规则:
JSON 语法是 JavaScript 对象表示法语法的子集。
数据在名称/值对中 
数据由逗号分隔 
花括号保存对象 
方括号保存数组
Java代码测试:
	//{"name":"zhangsan"}
	String json_1 = "{\"user_name\":\"zhangsan\"}";
	//对象{"user":"{"user_name":"lisi","sex":"男"}"}
	String json_2 = "{\"user\":{\"name\":\"lisi\",\"sex\":\"男\"}}";
	//数组{"users":"[{"user_name":"wangwu"},{"user_name":"zhaoliu"}]"}
	String json_3 = 
			"{\"users\":[{\"username\":\"wangwu\"},"
					  + "{\"username\":\"zhaoliu\"}]}";
	
	public void show(View view){
		try {
			JSONObject json1 = new JSONObject(json_1);
			System.out.println(json1.get("user_name"));
			JSONObject json2 = new JSONObject(json_2);
			System.out.println("user->" + json2.getJSONObject("user"));
			JSONObject j = new JSONObject(json_3);
			JSONArray array = j.getJSONArray("users");
			System.out.println("array:" + array);
		} catch (JSONException e) {
			e.printStackTrace();
		}
	}
效果:


你可能感兴趣的:(json,sax,dom,pull)