牛骨文教育服务平台(让学习变的简单)

Java之旅--XML/JSON

XML和JSON是两种常用的数据交换格式。虽然对于XML和JSON的各种操作,仅仅是常用的工具jar包的使用,没有什么技术含量,但鉴于这两种数据格式的普遍使用,还是拿出一点时间,进行一下简单总结。

XML

XML官网:http://www.xml.com/

XML保留字符有5个:&、>、<、"、""。

对于XML的解析方式,有两种:DOM方式和SAX方式。DOM是读入内存之后进行各种操作,SAX是流式操作、一次性的。其他的一些工具jar包,比如JDOM、DOM4J,都是对于这两种方式的高层次封装。

参考网址:

http://wenku.baidu.com/link?url=7VjI_4xMpWdV2O82WrNI2KO2UNuhefJYeGYe17QUmH89Nlc9NH20oVr8ZMJ2w1RSvphm5UE88L4FhB4fJgCcV4HldRlJsP9n_o1n1r7gunG

http://inotgaoshou.iteye.com/blog/1012188

DOM图示:

SAX图示:

演示代码:

import java.io.File;
import java.util.Stack;

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

import org.w3c.dom.Attr;
import org.w3c.dom.Comment;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

/**
 * 演示两种XML的解析方式:DOM和SAX
 * 
 * 至于JDOM和DOM4J,只是在这两种方式之上的更高层次的封装
 *
 */
public class XmlDemo {
	public static void main(String[] args) throws Exception {
		XmlDemo xmlDemo = new XmlDemo();

		// DOM方式
		DomDemo domDemo = xmlDemo.new DomDemo("src/main/java/com/cl/roadshow/java/xml/people.xml");
		domDemo.iterateByName("PERSON");
		domDemo.recursiveElement();

		// SAX方式
		SaxDemo saxDemo = xmlDemo.new SaxDemo("src/main/java/com/cl/roadshow/java/xml/people.xml");
		saxDemo.showEvents();
		saxDemo.parseDocument();
	}

	/**
	 * DOM方式解析XML
	 * 
	 */
	class DomDemo {
		private String path;

		public DomDemo(String path) {
			this.path = path;
		}

		/**
		 * 查询所有符合给到名称的Node,大小写敏感
		 * 
		 * @param tagName
		 * @throws Exception
		 */
		public void iterateByName(String tagName) throws Exception {
			// 获得DOM解析器工厂
			DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
			// 获得具体的DOM解析器
			DocumentBuilder db = dbf.newDocumentBuilder();
			// 解析XML文档,获得Document对象(根结点)
			Document doc = db.parse(new File(path));
			NodeList nodeList = doc.getElementsByTagName(tagName);

			for (int i = 0; i < nodeList.getLength(); i++) {

				Element element = (Element) nodeList.item(i);
				String content = element.getElementsByTagName("NAME").item(0).getFirstChild().getNodeValue();
				System.out.println("name:" + content);

				content = element.getElementsByTagName("ADDRESS").item(0).getFirstChild().getNodeValue();
				System.out.println("address:" + content);

				content = element.getElementsByTagName("TEL").item(0).getFirstChild().getNodeValue();
				System.out.println("tel:" + content);

				content = element.getElementsByTagName("FAX").item(0).getFirstChild().getNodeValue();
				System.out.println("fax:" + content);

				content = element.getElementsByTagName("EMAIL").item(0).getFirstChild().getNodeValue();
				System.out.println("email:" + content);

				System.out.println("--------------------------------------");
			}
		}

		/**
		 * 从根节点开始,遍历XML的所有元素
		 * 
		 * @throws Exception
		 */
		public void recursiveElement() throws Exception {
			DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
			DocumentBuilder db = dbf.newDocumentBuilder();

			Document doc = db.parse(new File(path));
			// 获得根元素结点
			Element root = doc.getDocumentElement();

			parseElement(root);
		}

		/**
		 * 递归方法
		 * 
		 * @param element
		 */
		private void parseElement(Element element) {

			String tagName = element.getNodeName();

			NodeList children = element.getChildNodes();

			System.out.print("<" + tagName);

			// element元素的所有属性所构成的NamedNodeMap对象,需要对其进行判断
			NamedNodeMap map = element.getAttributes();

			// 如果该元素存在属性
			if (null != map) {
				for (int i = 0; i < map.getLength(); i++) {
					// 获得该元素的每一个属性
					Attr attr = (Attr) map.item(i);

					String attrName = attr.getName();
					String attrValue = attr.getValue();

					System.out.print(" " + attrName + "="" + attrValue + """);
				}
			}

			System.out.print(">");

			for (int i = 0; i < children.getLength(); i++) {
				Node node = children.item(i);
				// 获得结点的类型
				short nodeType = node.getNodeType();

				if (nodeType == Node.ELEMENT_NODE) {
					// 是元素,继续递归
					parseElement((Element) node);
				} else if (nodeType == Node.TEXT_NODE) {
					// 递归出口
					System.out.print(node.getNodeValue());
				} else if (nodeType == Node.COMMENT_NODE) {
					System.out.print("<!--");

					Comment comment = (Comment) node;

					// 注释内容
					String data = comment.getData();

					System.out.print(data);

					System.out.print("-->");
				}
			}

			System.out.print("</" + tagName + ">");
		}
	}

	/**
	 * SAX方式解析XML
	 *
	 */
	class SaxDemo {
		private String path;

		public SaxDemo(String path) {
			this.path = path;
		}

		public void showEvents() throws Exception {

			// 获得SAX解析器工厂实例
			SAXParserFactory factory = SAXParserFactory.newInstance();

			// 获得SAX解析器实例
			SAXParser parser = factory.newSAXParser();

			// 开始进行解析
			parser.parse(new File(path), new EventHandler());
		}

		public void parseDocument() throws Exception {

			// 获得SAX解析器工厂实例
			SAXParserFactory factory = SAXParserFactory.newInstance();

			// 获得SAX解析器实例
			SAXParser parser = factory.newSAXParser();

			// 开始进行解析
			parser.parse(new File(path), new ParseHandler());
		}

		/**
		 * 演示SAX解析方式的事件驱动过程
		 *
		 */
		class EventHandler extends DefaultHandler {
			@Override
			public void startDocument() throws SAXException {
				System.out.println("
--------------------------------------");
				System.out.println("start document");
			}

			@Override
			public void endDocument() throws SAXException {
				System.out.println("finish document");
				System.out.println("--------------------------------------");
			}

			@Override
			public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
				System.out.println("start element");
			}

			@Override
			public void endElement(String uri, String localName, String qName) throws SAXException {
				System.out.println("finish element");
			}
		}

		/**
		 * 演示用SAX方式解析PERSON节点的过程
		 *
		 */
		class ParseHandler extends DefaultHandler {
			private Stack<String> stack = new Stack<String>();

			private String name;

			private String tel;

			@Override
			public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
				stack.push(qName);

				for (int i = 0; i < attributes.getLength(); i++) {
					String attrName = attributes.getQName(i);
					String attrValue = attributes.getValue(i);

					System.out.println(attrName + "=" + attrValue);
				}
			}

			@Override
			public void characters(char[] ch, int start, int length) throws SAXException {
				String tag = stack.peek();

				if ("NAME".equals(tag)) {
					name = new String(ch, start, length);
				} else if ("TEL".equals(tag)) {
					tel = new String(ch, start, length);
				}
			}

			@Override
			public void endElement(String uri, String localName, String qName) throws SAXException {
				stack.pop(); // 表示该元素已经解析完毕,需要从栈中弹出

				if ("PERSON".equals(qName)) {
					System.out.println("NAME:" + name);
					System.out.println("TEL:" + tel);

					System.out.println();
				}

			}
		}
	}
}

JSON

JSON官网:http://www.json.org/json-zh.html

对于JSON的解析,各种语言下都有 很多可用客户端,在Java下,fastjson是推荐使用的一种,快、强大、无依赖。

代码演示:

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

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

/**
 * fastjson 是一个性能很好的 Java 语言实现的 JSON 解析器和生成器,来自阿里巴巴的工程师开发
 * 
 * 
 * 主要特点:比其它任何基于Java的解析器和生成器更快,包括jackson;强大;零依赖
 *
 */
public class FastjsonDemo {
	public static void main(String[] args) {

		// 将JSON和JavaBean对象互相转换
		Person person = new Person(1, "张三", null);
		String jsonString = JSON.toJSONString(person);
		System.out.println(jsonString);
		person = JSON.parseObject(jsonString, Person.class);
		System.out.println(person.getName());

		System.out.println("--------------------------------------");

		// 将JSON字符串转化成List<JavaBean>对象
		Person person1 = new Person(1, "fastjson1", 11);
		Person person2 = new Person(2, "fastjson2", 22);
		List<Person> persons = new ArrayList<Person>();
		persons.add(person1);
		persons.add(person2);
		jsonString = JSON.toJSONString(persons);
		System.out.println("json字符串:" + jsonString);
		persons = JSON.parseArray(jsonString, Person.class);
		System.out.println(persons.toString());

		System.out.println("--------------------------------------");

		// 将JSON字符串转化成List<String>对象
		List<String> list1 = new ArrayList<String>();
		list1.add("fastjson1");
		list1.add("fastjson2");
		list1.add("fastjson3");
		jsonString = JSON.toJSONString(list1);
		System.out.println(jsonString);
		List<String> list2 = JSON.parseObject(jsonString, new TypeReference<List<String>>() {
		});
		System.out.println("list2:" + list2.toString());

		System.out.println("--------------------------------------");

		// JSON<Map<String,Object>>对象
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("key1", "value1");
		map.put("key2", "value2");
		Map<String, Object> map2 = new HashMap<String, Object>();
		map2.put("key1", 1);
		map2.put("key2", 2);
		List<Map<String, Object>> list3 = new ArrayList<Map<String, Object>>();
		list3.add(map);
		list3.add(map2);
		jsonString = JSON.toJSONString(list3);
		System.out.println("json字符串:" + jsonString);
		List<Map<String, Object>> list4 = JSON.parseObject(jsonString, new TypeReference<List<Map<String, Object>>>() {
		});
		System.out.println("list4:" + list4.toString());
	}
}

class Person {

	private Integer id;
	private String name;
	private Integer age;

	public Person() {
	}

	public Person(Integer id, String name, Integer age) {
		super();
		this.id = id;
		this.name = name;
		this.age = age;
	}

	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public Integer getAge() {
		return age;
	}

	public void setAge(Integer age) {
		this.age = age;
	}

	@Override
	public String toString() {
		StringBuilder sb = new StringBuilder();
		sb.append("ID:").append(id);
		sb.append("-Name:").append(name);
		sb.append("-Age:").append(age);
		return sb.toString();
	}
}