两个数据格式(xml,json)的解析

版权声明:转载请申明出处,谢谢 https://blog.csdn.net/qq_35495763/article/details/87817987

update time:2019/2/20 Author:要你命三千又三千 type:学习笔记

xml数据的解析

使用java中的数据解析方法

简介

java中有四种数据的解析方法

  • 1、DOM解析
  • 2、SAX解析
  • 3、JDOM解析
  • 4、DOM4J解析
    前两种属于基础方法,是官方提供的平台无关的解析方式;
    后两种属于扩展方法,它们是在基础的方法上扩展出来的,只适用于java平台。

DOM解析

Dom解析是将xml文件全部载入到内存,组装成一颗DOM树,然后通过节点以及节点之间的关系来解析xml文件。由于DOM分析器把整个XML文档转化成DOM树放在了内存中,因此,当文档比较大或者结构比较复杂时,对内存的需求就比较高。而且,对于结构复杂的树的遍历也是一项耗时的操作。所以,DOM分析器对机器性能的要求比较高,实现效率不十分理想

使用DOM来解析XML文件


public class TestXml {
	public static void main(String[] args) {
		try {
			try {
				// 新建DOM解析工廠
				DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
				// 获取DOM解析器
				DocumentBuilder db = dbf.newDocumentBuilder();
				// 解析文档,获取根节点Document对象
				//(在windows系统中一律使用双斜杠,来代替linux系统中单个反斜杠)
				Document document = (Document) db.parse(new File("src\\lesson\\student.xml"));
				// 分別打印文档编码,版本,是否为独立文档
				System.out.println(document.getXmlEncoding());
				System.out.println(document.getXmlVersion());
				System.out.println(document.getXmlStandalone());
			    //获取元素节点列表
				NodeList nList=document.getElementsByTagName("student");
				for (int i = 0; i < nList.getLength(); i++) {
					Element node=(Element)nList.item(i);
					System.out.println("id"+node.getAttribute("id"));
					System.out.println("name"+node.getElementsByTagName("name").item(0).getFirstChild().getNodeValue());
					System.out.println("birthday"+node.getElementsByTagName("birthday").item(0).getFirstChild().getNodeValue());
					System.out.println("email"+node.getElementsByTagName("email").item(0).getFirstChild().getNodeValue());
				}		
			} catch (SAXException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {				
				e.printStackTrace();
			}
		} catch (ParserConfigurationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}
<?xml version="1.0" encoding="UTF-8"?>
<students>
	<student id="1201">
		<name>王明</name>
		<birthday>1995-12</birthday>
		<email>[email protected]</email>
	</student>
	<student id="1202">
		<name>李娟</name>
		<birthday>1996-1</birthday>
		<email>[email protected]</email>
	</student>
</students>

文件所在的路径
在这里插入图片描述
补充的几点说明

  1. Xml 文档所有都被称之为节点

Node对象是DOM中最基本的对象,代表了文档树中的抽象节点。但在实际使用中很少使用 而是使用Node对象的子对象Element、attr、Text。

  1. 节点有三个子类,元素类,属性类,文本类。
  2. NodeList是一个colllection所以使用for循环item()来遍历
  3. 获取到文本节点,然后使用getNodeValue()来获取文本值。

SAX解析

SAX与DOM不同的是它边扫描边解析,自顶向下依次解析,由于边扫描边解析,所以它解析XML具有速度快,占用内存少的优点。

SAX的优点:

  1. 解析速度快
  2. 占用内存少

SAX的缺点

  1. 无法知道当前解析标签(节点)的上层标签,及其嵌套结构,仅仅知道当前解析的标签的名字和属性,要知道其他信息需要程序猿自己编码
  2. 只能读取XML,无法修改XML
  3. 无法随机访问某个标签(节点)
public class SAXTest {
	public static void main(String[] args) {	
		try {		
			SAXParserFactory factory= SAXParserFactory.newInstance();
	        //得到解析器
	         SAXParser	sp = factory.newSAXParser();
			 //得到解读器
	        XMLReader reader=sp.getXMLReader();
	        //设置内容处理器
	        reader.setContentHandler(new ListHandler());
	        //读取xml的文档内容
	        reader.parse("src/Book.xml");
            
		} catch (ParserConfigurationException | SAXException | IOException e) {
			e.printStackTrace();
		}  
	}
}

建立对应的handler

package lesson;
public class ListHandler implements ContentHandler {
	@Override
    public void startElement(String uri, String localName, String qName,
            Attributes atts) throws SAXException {
        System.out.print("<"+qName);
        for(int i=0; atts!=null && i<atts.getLength(); i++){
            String attName=atts.getQName(i);
            String attValueString=atts.getValue(i);
            System.out.print(" "+attName+"=\""+attValueString+"\"");   
        }
        System.out.print(">");     
    }
    /**
     * 表示读取到第一个元素结尾时做什么
     */
    @Override
    public void endElement(String uri, String localName, String qName)
            throws SAXException {
        System.out.print("</"+qName+">");   
    }
    /**
     * 表示读取字符串时做什么
     */
    @Override
    public void characters(char[] ch, int start, int length)
            throws SAXException {
        System.out.print(new String(ch,start,length));
    }
	@Override
	public void endPrefixMapping(String prefix) throws SAXException {
		// TODO Auto-generated method stub	
	}
	@Override
	public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException {
		// TODO Auto-generated method stub
	}
	@Override
	public void processingInstruction(String target, String data) throws SAXException {
		// TODO Auto-generated method stub
		}
	@Override
	public void setDocumentLocator(Locator locator) {
		// TODO Auto-generated method stub	
	}
	@Override
	public void skippedEntity(String name) throws SAXException {
		// TODO Auto-generated method stub	
	}
	@Override
	public void startDocument() throws SAXException {
		// TODO Auto-generated method stub	
	}
	@Override
	public void endDocument() throws SAXException {
		// TODO Auto-generated method stub	
	}
	@Override
	public void startPrefixMapping(String prefix, String uri) throws SAXException {
		// TODO Auto-generated method stub	
	}
}
<?xml version="1.0" encoding="UTF-8"?>
<书架  xmlns:sina="http://www.sina.com" >
    <>
        <sina:书名 name="dddd">java web就业</sina:书名>
        <作者>张三</作者>
        <售价>40</售价> 
    </>
    <>
        <书名 name="xxxx">HTML教程</书名>
        <作者>自己</作者>
        <售价>50</售价> 
    </>
</书架>

说明:

  1. uri:元素所在的命名空间。如果元素没有名称空间 URI,或者未执行名称空间处理,则为空字符串.

  2. localName - 本地名称(不带前缀),如果未执行名称空间处理,则为空字符串 。

  3. qName - 限定的 XML 名称(带前缀),如果限定名不可用,则为空字符串

  4. startDocument()
    当遇到文档的开头的时候,调用这个方法,可以在其中做一些预处理的工作。

  5. endDocument()
    和上面的方法相对应,当文档结束的时候,调用这个方法,可以在其中做一些善后的工作。

  6. startElement(String uri, String localName, String qName, Attributes atts)
    当读到一个开始标签的时候,会触发这个方法。uri是命名空间(通过xmlns声明),localName是不带命名空间前缀的标签名,qName是带命名空间前缀的标签名。通过atts可以得到所有的属性名和相应的值。

 <?xml version="1.0" encoding="UTF-8"?>  
<web-app version="2.5"   
    xmlns:csdn="http://java.sun.com/xml/ns/javaee"   
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"   
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee   
    http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">  
  <csdn:display-name></csdn:display-name>     
</web-app>  

解析所的结果是
在这里插入图片描述

PULL解析(google提供的解析方式)

Json数据格式的解析

json的来源

  • JSON 指的是 JavaScript 对象表示法(JavaScript Object Notation)
    JSON 独立于语言:JSON 使用 Javascript语法来描述数据对象,但是 JSON 仍然独立于语言和平台。JSON 解析器和 JSON 库支持许多不同的编程语言。 目前非常多的动态(PHP,JSP,.NET)编程语言都支持JSON。

json作用

  • JSON 是轻量级的文本数据交换格式
  • 存储和交换文本信息的,类似 XML。
    JSON 比 XML 更小、更快,更易解析。

json 的语法规则
JSON 语法是 JavaScript 对象表示法语法的子集。

  1. 数据在名称/值对中
  2. 数据由逗号分隔
  3. 花括号保存对象
  4. 方括号保存数组

json的数值类型

  1. 数字(整数或浮点数)
  2. 字符串(在双引号中)
  3. 逻辑值(true 或 false)
  4. 数组(在方括号中)
  5. 对象(在花括号中)
  6. null字符串(在双引号中)

使用JSONObject来解析json数据

主要是分为两类:

  • 基本类型如Number、boolean等
    基本类型的解析直接调用JSONObject对象的getXxx(key)方法,如果获取字符串则getString(key),布尔值则getBoolean(key),以此类推。
  • 数组。
    数组的解析稍微麻烦一点,需要通过JSONObject对象的getJSONArray(key)方法获取到一个JSONArray对象,再调用JSONArray对象的get(i)方法获取数组元素,i为索引值。

实例:

使用时需要导入的包:https://download.csdn.net/download/justinqin/10158995

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
public class JSONObjectTest {
	public static void main(String[] args) {
		 String JSONdata = "[\n" + "  {\"id\":\"1\",\"version\":\"1.5\",\"name\":\"Apple\"},\n"					+ "  {\"id\":\"2\",\"version\":\"1.6\",\"name\":\"WillFlow\"},\n"				+ "  {\"id\":\"3\",\"version\":\"1.7\",\"name\":\"WGH\"}\n" + "]";
			parseJSONWithJSONObject(JSONdata);
	}
	
	static void parseJSONWithJSONObject(String jsonData) {
		try {
		//加载字符串数据
			JSONArray jsonArray = JSONArray.fromObject(jsonData);
			for (int i = 0; i < jsonArray.size(); i++) {
				JSONObject jsonObject = jsonArray.getJSONObject(i);
				String id = jsonObject.getString("id");
				String name = jsonObject.getString("name");
				String version = jsonObject.getString("version");
				System.out.println("id" + id);
				System.out.println("name" + name);
				System.out.println("version" + version);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

使用Gson解析

Gson是一个可以将Java对象序列化成JSON表示,也可以将JSON字符串转化成Java对象的Java库(谷歌提供)
Gson由于解析json (即反序列化),Gson用于将各类数据类型(包括对象,集合等)进行序列化和反序列化进行。
gson所需的jar包
链接:http://pan.baidu.com/s/1gfP8Zrt 密码:d994

实例:解析一个json数组的方式

package lesson;
import java.util.List;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
public class GsonLearn {
    /**
    *数据格式
     * [
      {"id":"1","version":"1.5","name":"Apple"},
      {"id":"2","version":"1.6","name":"WillFlow"},
      {"id":"3","version":"1.7","name":"WGH"}
         ]
     */
	static String Gsondata="[{\"id\":\"1\",\"version\":\"1.5\",\"name\":\"Apple\"},{\"id\":\"2\",\"version\":\"1.6\",\"name\":\"WillFlow\"}, {\"id\":\"3\",\"version\":\"1.7\",\"name\":\"WGH\"}]";
	
public static void main(String[] args) {	
	parseByGSON(Gsondata);
}
/**
 * 这里的利用TypeToken来实现gson数组数据的对象化
 * @param jsonData
 */
private static void parseByGSON(String jsonData) {
	
    Gson gson = new Gson();
    //生成了集合类型
    List<AppBean> appList = gson.fromJson(jsonData, new TypeToken<List<AppBean>>() {}.getType());
    //对集合的遍历访问
    for (AppBean app : appList) {
    	System.out.println("name"+app.getName());
    	System.out.println("version"+app.getVersion());  
    	System.out.println("id"+app.getId());
    }
}

}
 class AppBean {
    /**
     * id : 1
     * version : 1.5
     * name : Apple
     */
    private String id;
    private String version;
    private String name;

    public String getId() {
        return id;
    }

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

    public String getVersion() {
        return version;
    }

    public void setVersion(String version) {
        this.version = version;
    }

    public String getName() {
        return name;
    }

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

实例:使用Gson来解析一个对象

json 数据

{“name”:“Tom”,“age”:20}

那我们就可以定义一个 Person 类,并加入 name 和 age 这两个字段,然后只需简单地调用如下代码就可以将 JSON 数据自动解析成一个 Person 对象了:

Gson gson = new Gson();
Person person = gson.fromJson(jsonData, Person.class);

猜你喜欢

转载自blog.csdn.net/qq_35495763/article/details/87817987