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>
文件所在的路径
补充的几点说明
- Xml 文档所有都被称之为节点
Node对象是DOM中最基本的对象,代表了文档树中的抽象节点。但在实际使用中很少使用 而是使用Node对象的子对象Element、attr、Text。
- 节点有三个子类,元素类,属性类,文本类。
- NodeList是一个colllection所以使用for循环item()来遍历
- 获取到文本节点,然后使用getNodeValue()来获取文本值。
SAX解析
SAX与DOM不同的是它边扫描边解析,自顶向下依次解析,由于边扫描边解析,所以它解析XML具有速度快,占用内存少的优点。
SAX的优点:
- 解析速度快
- 占用内存少
SAX的缺点
- 无法知道当前解析标签(节点)的上层标签,及其嵌套结构,仅仅知道当前解析的标签的名字和属性,要知道其他信息需要程序猿自己编码
- 只能读取XML,无法修改XML
- 无法随机访问某个标签(节点)
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</售价>
</书>
</书架>
说明:
-
uri:元素所在的命名空间。如果元素没有名称空间 URI,或者未执行名称空间处理,则为空字符串.
-
localName - 本地名称(不带前缀),如果未执行名称空间处理,则为空字符串 。
-
qName - 限定的 XML 名称(带前缀),如果限定名不可用,则为空字符串
-
startDocument()
当遇到文档的开头的时候,调用这个方法,可以在其中做一些预处理的工作。 -
endDocument()
和上面的方法相对应,当文档结束的时候,调用这个方法,可以在其中做一些善后的工作。 -
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 对象表示法语法的子集。
- 数据在名称/值对中
- 数据由逗号分隔
- 花括号保存对象
- 方括号保存数组
json的数值类型
- 数字(整数或浮点数)
- 字符串(在双引号中)
- 逻辑值(true 或 false)
- 数组(在方括号中)
- 对象(在花括号中)
- 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);