第四章. XML与Json文件处理

1. XML简介

1.1 XML(eXtensible Markup Language)

:是一种数据存储格式

  1. 可扩展标记语言:数据 + 含义
  2. 标签可自行定义,具有自我描述性
  3. 纯文本表示,跨系统/平台/语言

常规语法

  1. 任何的起始标签都必须有一个结束标签。
  2. 大小写敏感,如<name>和<Name>不一样。
  3. 所有标签的属性都必须有值,且在值的周围加上引号。
  4. 注释:<!-- 注释内容 -->
<bookstore>
	<book category="CHILDREN">
		<title lang="en">Harry Potter</title>
		<author>J K. Rowling</author>
		<year>2005</year>
		<price>29.99</price>
	</book>
	<book category="WEB">
		<title lang="en">Learning XML</title>
		<author>Erik T. Ray</author>
		<year>2003</year>
		<price>39.95</price>
	</book>
</bookstore>

即:在这里插入图片描述

1.2 XML Schema(XSD,XML Schema Definition)

– 定义 XML 文档的结构
– 支持数据类型,可扩展,功能更完善、强大
– 采用xml编写

<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.w3school.com.cn"
xmlns="http://www.w3school.com.cn"
elementFormDefault="qualified">

	<xs:element name="note">
	    <xs:complexType>
	      <xs:sequence>
		<xs:element name="to" type="xs:string"/>
		<xs:element name="from" type="xs:string"/>
		<xs:element name="heading" type="xs:string"/>
		<xs:element name="body" type="xs:string"/>
	      </xs:sequence>
	    </xs:complexType>
	</xs:element>
	

</xs:schema>

2.XML处理

XML解析方法

  1. 树结构
    • DOM: Document Object Model 文档对象模型,擅长(小规模)读/写
  2. 流结构
    • SAX: Simple API for XML 流机制解释器(推模式),擅长读
    • Stax: The Streaming API for XML 流机制解释器(拉模式),擅长读,

2.1 XML解析(DOM)

:DOM
– 其处理方式是将 XML 整个作为类似树结构的方式读入内存中以便操作及解析,方便修改。
– 解析大数据量的 XML 文件,会遇到内存泄露及程序崩溃的风险。

主要类:DOM类
• DocumentBuilder 解析类,parse方法
• Node 节点主接口,getChildNodes返回一个NodeList
• NodeList 节点列表,每个元素是一个Node
• Document 文档根节点
• Element 标签节点元素 (每一个标签都是标签节点)
• Text节点 (包含在XML元素内的,都算Text节点)
• Attr节点(每个属性节点)

2.2 XML解析(SAX)

Simple API for XML

  1. 推模型。当它每发现一个节点就引发一个事件,而我们需要编写这些事件的处理程序。(继承DefaultHandler)
  2. 采用事件/流模型来解析 XML 文档,更快速、更轻量。
  3. 有选择的解析和访问,不像 DOM 加载整个文档,内存要求较低。
    – SAX 对 XML 文档的解析为一次性读取,不创建/不存储文档对象,很难同时访问文档中的多处数据。
    在这里插入图片描述

关键类:org.xml.sax

2.3 XML解析(Stax)

Streaming API for XML

  1. 流模型中的拉模型
  2. 在遍历文档时,会把感兴趣的部分从读取器中拉出,不需要引发
    事件,允许我们选择性地处理节点。这大大提高了灵活性,以及
    整体效率。

两套处理API
• 基于指针的API, XMLStreamReader
• 基于迭代器的API,XMLEventReader

基于指针的API:XMLStreamReader

package xml.stax;

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.Iterator;

import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.events.Attribute;
import javax.xml.stream.events.EndElement;
import javax.xml.stream.events.StartElement;
import javax.xml.stream.events.XMLEvent;


public class StaxReader {
	
	public static void main(String[] args) {
		StaxReader.readByStream();
		System.out.println("========华丽丽的分割线==========");
		StaxReader.readByEvent();
	}

	//流模式
	public static void readByStream() {
		String xmlFile = "books.xml";
		XMLInputFactory factory = XMLInputFactory.newFactory();
		XMLStreamReader streamReader = null;
		try {
			streamReader = factory.createXMLStreamReader(new FileReader(xmlFile));			
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (XMLStreamException e) {
			e.printStackTrace();
		}
		
		// 基于指针遍历
		try {
			while (streamReader.hasNext()) {
				int event = streamReader.next();
				// 如果是元素的开始
				if (event == XMLStreamConstants.START_ELEMENT) {
					// 列出所有书籍名称
					if ("title".equalsIgnoreCase(streamReader.getLocalName())) {
						System.out.println("title:" + streamReader.getElementText());
					}
				}
			}
			streamReader.close();
		} catch (XMLStreamException e) {
			e.printStackTrace();
		}
	}
	

在这里插入图片描述
DOM/SAX/Stax是JDK自带的解析功能。
• 第三方库
– JDOM: www.jdom.org
– DOM4J: dom4j.github.io
• 第三方库一般都包含DOM,SAX等多种方式解析,是对Java
解析进行封装。


3.Json

JSON:一种数据存储交换格式

  1. JavaScript Object Notation, JS 对象表示法
  2. 类似XML,更小、更快、更易解析
  3. 尽管使用Javascript语法,但是独立于编程语言

JSONObject

  • 名称/值对。如"firstName":“John”
    – JSON对象:{“name":“Jo”,“email”:“a@b.com”}
    – 数据在键值对中
    – 数据由逗号分隔
    – 花括号保存对象

JSON数组

  • 方括号保存数组
    [{“name":“Jo”,“email”:“a@b.com”}, {“name":“Jo”,“email”:“a@b.com”}]

JSON 主要用途

  1. JSON生成
  2. JSON解析
    20 JSON校验
  3. Java Bean对象进行互解析
    – 具有一个无参的构造函数
    – 可以包括多个属性,所有属性都是private
    – 每个属性都有相应的Getter/Setter方法

Java的JSON处理(主要类库)

  1. org.json:JSON官方推荐的解析类
    – 简单易用,通用性强
    – 复杂功能欠缺
  2. GSON:Google出品
    – 基于反射,可以实现JSON对象、JSON字符串和Java对象互转
  3. Jackson:号称最快的JSON处理器
    – 简单易用,社区更新和发布速度比较快

GSON:

import java.io.File;
import java.io.FileReader;
import java.util.Arrays;
import java.util.List;

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

/**
 * 采用Google GSON来处理JSON
 * @author Tom
 *
 */
public class GsonTest {
	public static void main(String[] args) {
		testJsonObject();
		System.out.println("=========华丽丽的分割线==============");
		testJsonFile();
	}
	public static void testJsonObject() {
		//构造对象
    	Person p = new Person();
    	p.setName("Tom");
    	p.setAge(20);
    	p.setScores(Arrays.asList(60,70,80));
		
    	//从Java对象到JSON字符串
		Gson gson = new Gson();
		String s = gson.toJson(p);
		System.out.println(s); //{"name":"Tom","age":20,"scores":[60,70,80]}
		
		//从JSON字符串到Java对象
		Person p2 = gson.fromJson(s, Person.class);
		System.out.println(p2.getName());  //Tom
		System.out.println(p2.getAge());   //20
		System.out.println(p2.getScores());//[60, 70, 80]
		
		//调用GSON的JsonObject
		JsonObject json = gson.toJsonTree(p).getAsJsonObject(); //将整个json解析为一颗树
		System.out.println(json.get("name"));  //"Tom"
		System.out.println(json.get("age"));   //20
		System.out.println(json.get("scores"));//[60,70,80]
		
	}
	
	public static void testJsonFile() {
		Gson gson = new Gson();
		File file = new File("books2.json");
		
        try (FileReader reader = new FileReader(file)) {
        	List<Book> books = gson.fromJson(reader, new TypeToken<List<Book>>(){}.getType());
            
        	for(Book book : books)
        	{
        		System.out.println(book.getAuthor() + ",  " + book.getTitle());
        	}
        } catch (Exception e) {
            e.printStackTrace();
        }
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值