一、XML
二、XML解析的四种方式
一、SAX解析
- SAX解析
解析方式是事件驱动机制 !
SAX解析器, 逐行读取XML文件解析 , 每当解析到一个标签的开始/结束/内容/属性时,触发事件.
我们可以编写程序在这些事件发生时, 进行相应的处理.
优点:
分析能够立即开始,而不是等待所有的数据被处理
逐行加载,节省内存.有助于解析大于系统内存的文档
有时不必解析整个文档,它可以在某个条件得到满足时停止解析.
缺点:- 单向解析,无法定位文档层次,无法同时访问同一文档的不同部分数据(因为逐
行解析, 当解析第n行是, 第n-1行已经被释放了, 无法在进行操作了).- 无法得知事件发生时元素的层次, 只能自己维护节点的父/子关系.
- 只读解析方式, 无法修改XML文档的内容.
二、DOM解析
1、是用与平台和语言无关的方式表示XML文档的官方W3C标准,分析该结构通常需要加载整个
2、文档和内存中建立文档树模型.程序员可以通过操作文档树, 来完成数据的获取 修改 删除等.
3、优点:
文档在内存中加载, 允许对数据和结构做出更改.
访问是双向的,可以在任何时候在树中双向解析数据。
4、缺点:
文档全部加载在内存中 , 消耗资源大.
三、JDOM解析
1、目的是成为Java特定文档模型,它简化与XML的交互并且比使用DOM实现更快。由于是第一个Java特定模型,JDOM一直得到大力推广和促进。
JDOM文档声明其目的是“使用20%(或更少)的精力解决80%(或更多)Java/XML问题”(根据学习曲线假定为20%)
2、优点:
使用具体类而不是接口,简化了DOM的API。
大量使用了Java集合类,方便了Java开发人员。
3、缺点:
DOM4J解析XML 掌握
文档对象 Document
元素对象 Element
没有较好的灵活性。
性能不是那么优异。
四、DOM4J解析
它是JDOM的一种智能分支。它合并了许多超出基本XML文档表示的功能,包括集成的XPath
支持、XML Schema支持以及用于大文档或流化文档的基于事件的处理。它还提供了构建文档表示的选项,DOM4J是一个非常优秀的Java XML API,具有性能优异、功能强大和极端易用使用的特点,同时它也是一个开放源代码的软件。如今你可以看到越来越多的Java软件都在使用DOM4J来读写XML。
目前许多开源项目中大量采用DOM4J , 例如:Hibernate
三、Dom4j
一、下载.jar包
二、在ideal种导入.jar包
1、创建一个java项目
2、在项目下创建一个lib文件夹
2、将jar文件复制到lib文件夹种
3、按住ctrl+alt+shfit+s
三、进行Dom4j解析
- 引入jar文件 dom4j.jar
- 创建一个指向XML文件的输入流
FileInputStream fis = new FileInputStream(“xml文件的地址”);- 创建一个XML读取工具对象
SAXReader sr = new SAXReader();- 使用读取工具对象, 读取XML文档的输入流 , 并得到文档对象
Document doc = sr.read(fis);- 通过文档对象, 获取XML文档中的根元素对象
Element root = doc.getRootElement();
public class test { public static void main(String[] args) throws FileNotFoundException, >DocumentException { FileInputStream fis=new FileInputStream("src\\test.xml"); SAXReader sr=new SAXReader(); Document doc=sr.read(fis); Element root=doc.getRootElement(); System.out.println(root.getName()); }
文档对象:Document
- 通过文档对象, 获取XML文档中的根元素对象
Element root = doc.getRootElement();- 添加根节点
Element root = doc.addElement(“根节点名称”);
元素对象 Element
- 获取节点名称
String getName();- 获取节点内容
String getText();- 设置节点内容
String setText();- 根据子节点的名称 , 获取匹配名称的第一个子节点对象.
Element element(String 子节点名称);- 获取所有的子节点对象
List < Element> elements();- 获取节点的属性值
String attributeValue(String 属性名称);- 获取子节点的内容
String elementText(String 子节点名称);- 添加子节点
Element addElement(String 子节点名称);- 添加属性
void addAttribute(String 属性名,String 属性值);
解析本地文件案例
//1. 获取文件的输入流
FileInputStream fis = new
FileInputStream("C:\\code\\35\\code1\\day03_XML\\src\\books.xml");
//2. 创建XML读取工具对象
SAXReader sr = new SAXReader();
//3. 通过读取工具, 读取XML文档的输入流 , 并得到文档对象
Document doc = sr.read(fis);
//4. 通过文档对象 , 获取文档的根节点对象
Element root = doc.getRootElement();
//5. 通过根节点, 获取所有子节点
List<Element> es = root.elements();
//6. 循环遍历三个book
for (Element e : es) {
//1. 获取id属性值
String id = e.attributeValue("id");
//2. 获取子节点name , 并获取它的内容
String name = e.element("name").getText();
//3. 获取子节点info , 并获取它的内容
String info = e.element("info").getText();
System.out.println("id="+id+",name="+name+",info="+info);
}
解析网络文件案例:
String phone = "18516955565";
//1. 获取到XML资源的输入流
URL url = new URL("http://apis.juhe.cn/mobile/get?
phone="+phone+"&dtype=xml&key=9f3923e8f87f1ea50ed4ec8c39cc9253");
URLConnection conn = url.openConnection();
InputStream is = conn.getInputStream();
//2. 创建一个XML读取对象
SAXReader sr = new SAXReader();
//3. 通过读取对象 读取XML数据,并返回文档对象
Document doc = sr.read(is);
//4. 获取根节点
Element root = doc.getRootElement();
//5. 解析内容
String code = root.elementText("resultcode");
if("200".equals(code)){
Element result = root.element("result");
String province = result.elementText("province");
String city = result.elementText("city");
if(province.equals(city)){
System.out.println("手机号码归属地为:"+city);
}else{
System.out.println("手机号码归属地为:"+province+" "+city);
}
}else{
System.out.println("请输入正确的手机号码");
}
四、Xpath解析
在Java中使用xpath方法,主要有两点:
List selectNodes(“xpath表达式”); 查询多个节点对象
Node selectSingleNode(“xpath表达式”); 查询一个节点对象
一、List selectNodes(“xpath表达式”); 查询多个节点对象
通过路径快速的查找一个或一组元素
路径表达式:
- / : 从根节点开始查找
- // : 从发起查找的节点位置 查找后代节点 ***
- . : 查找当前节点
- … : 查找父节点
- @ : 选择属性. *
属性使用方式:
[@属性名=‘值’]
[@属性名>‘值’]
[@属性名<‘值’]
[@属性名!=‘值’]
books: 路径: //book[@id=‘1’]//name
books
book id=1
name
info
book id=2
name
info
public class test {
public static void main(String[] args) throws Exception {
Document doc = new SAXReader().read(new File("./src/books.xml"));
String xpath="";
//1. / 绝对路径 表示从xml的根位置开始或子元素(一个层次结构)
xpath = "/contactList";
xpath = "/contactList/contact";
//2. // 相对路径 表示不分任何层次结构的选择元素。
xpath = "//contact/name";
xpath = "//name";
//3. * 通配符 表示匹配所有元素
xpath = "/contactList/*"; //根标签contactList下的所有子标签
xpath = "/contactList//*";//根标签contactList下的所有标签(不分层次结构)
//4. [] 条件 表示选择什么条件下的元素
// 带有id属性的contact标签
xpath = "//contact[@id]";
//第二个的contact标签
xpath = "//contact[2]";
//选择最后一个contact标签
xpath = "//contact[last()]";
//5. @ 属性 表示选择属性节点
xpath = "//@id"; //选择id属性节点对象,返回的是Attribute对象
xpath = "//contact[not(@id)]";//选择不包含id属性的contact标签节点
xpath = "//contact[@id='002']";//选择id属性值为002的contact标签
xpath = "//contact[@id='001' and @name='eric']";//选择id属性值为001,且name属性为eric的contact标签
// 6. text() 表示选择文本内容
//选择name标签下的文本内容,返回Text对象
xpath = "//name/text()";
xpath = "//contact/name[text()='张三']";//选择姓名为张三的name标签
xpath="/books/name";
List<Node> list = doc.selectNodes(xpath);
for (Node node : list) {
System.out.println(node);
}
//写出xml文件
//输出位置
FileOutputStream out = new FileOutputStream("src\\contact.xml");
//指定格式
OutputFormat format = OutputFormat.createPrettyPrint();
format.setEncoding("utf-8");
XMLWriter writer = new XMLWriter(out,format);
//写出内容
writer.write(doc);
//关闭资源
writer.close();
}
二、selectSingleNode的使用方法
public class test{
public static void main(String[] args) throws Exception{
//读取XML文件,获得document对象
SAXReader saxReader = new SAXReader();
Document doc = saxReader.read(new FileInputStream("src\\books.xml"));
//使用xpath获取某个节点
String xpath = "";
//对contact元素 id="001"的节点,操作
xpath = "//book[@id ='100']";
Element contactElem = (Element)doc.selectSingleNode(xpath);
//设置这个节点的属性值
contactElem.addAttribute("name", "001");
//输出这个节点的所有属性值
for(Iterator it = contactElem.attributeIterator();it.hasNext();){
Attribute conAttr = (Attribute)it.next();
String conTxt = conAttr.getValue();
String conAttrName = conAttr.getName();
System.out.println(conAttrName+" = "+conTxt);
}
}
}
五、XML生成
public class test {
public static void main(String[] args) throws IOException, DocumentException {
//1、 通过文档帮助器 创建一个文档对象
Document doc= DocumentHelper.createDocument();
//2、 给文档添加第一个子节点(根节点)
Element books=doc.addElement("books");
//3、 通过根节点丰富字节点
for(int i=0;i<100;i++){
Element book=books.addElement("book");
Element name=books.addElement("name");
name.setText(i+"中苹果的小姑娘");
Element info=book.addElement("info");
info.setText(i+"辛勤种植苹果的故事");
book.addAttribute("id",100+i+"");
}
//4、 创建一个文件输出流
FileOutputStream fos=new FileOutputStream("src\\books.xml");
//5、 将输出流转换为XML输出流
XMLWriter xw=new XMLWriter(fos);
//6、 写出文档
xw.write(doc);
//7、 释放资源
xw.close();
}
}
通过XStream方式生成
快速的将Java中的对象, 转换为 XML字符串.1. 创建XStream 对象 XStream x = new XStream(); 2.修改类生成的节点名称 (默认节点名称为 包名.类名) x.alias("节点名称",类名.class); 3. 传入对象 , 生成XML字符串 String xml字符串 = x.toXML(对象);
public class test {
public static void main(String[] args) throws IOException, DocumentException {
Person p=new Person();
p.setAge(18);
p.setName("张三");
//XStream使用
//1、创建XStream对象
XStream x=new XStream();
//2、修改某个类型生成的节点(可选 默认为包名.类名)
x.alias("person",Person.class);
//3、传入对象 开始生成
String xml=x.toXML(p);
System.out.println(xml);
}
static class Person{
private String name;
private int age;
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Person person = (Person) o;
return age == person.age &&
Objects.equals(name, person.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
public Person() {
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
}
}
六、JSON
JSON: JavaScript Object Notation JS对象简谱 , 是一种轻量级的数据交换格式.
对象格式一本书 书名 简介 java class Book{ private String name; private String info; 数组格式 案例 get/set... } Book b = new Book(); b.setName(“金苹果”); b.setInfo(“种苹果”); ... js: var b = new Object(); b.name = "金苹果"; b.info = "种苹果"; XML: <book> <name>金苹果</name> <info>种苹果</info> </book> JSON: { "name":"金苹果", "info":"种苹果" } 一个对象, 由一个大括号表示. 括号中 描述对象的属性 . 通过键值对来描述对象的属性 (可以理解为, 大括号中, 包含的是一个个的键值对.) 格式: 键与值之间使用冒号连接, 多个键值对之间使用逗号分隔. 键值对的键 应使用引号引住 (通常Java解析时, 键不使用引号会报错. 而JS能正>确解 析.) 键值对的值, 可以是JS中的任意类型的数据
数组格式
在JSON格式中可以与对象互相嵌套 [元素1,元素2...]
案例
{ "name":"伟杰老师", "age":18, "pengyou":["张三","李四","王二","麻子",{ "name":"野马老师", "info":"像匹野马一样狂奔在技术钻研的道路上" }], "heihei":{ "name":"大长刀", "length":"40m" } }
Java与JSON
做什么? 将Java中的对象 快速的转换为 JSON格式的字符串. 将JSON格式的字符串, 转换为Java的对象.
Gson:将对象转换为JSON字符串
转换JSON字符串的步骤: 1. 引入JAR包 2. 在需要转换JSON字符串的位置编写如下代码即可: String json = new Gson().toJSON(要转换的对象); 案例: Book b = BookDao.find(); String json = new Gson().toJson(b); System.out.println(json);
将JSON字符串转换为对象
1. 引入JAR包 2. 在需要转换Java对象的位置, 编写如下代码: 对象 = new Gson().fromJson(JSON字符串,对象类型.class); 案例: String json = "{\"id\":1,\"name\":\"金苹果\",\"author\":\"李伟杰 \",\"info\":\"嘿嘿嘿嘿嘿嘿\",\"price\":198.0}"; Book book = new Gson().fromJson(json, Book.class); System.out.println(book);
FastJson:将对象转换为JSON字符串
转换JSON字符串的步骤: 1. 引入JAR包 2. 在需要转换JSON字符串的位置编写如下代码即可: String json=JSON.toJSONString(要转换的对象); 案例: Book b = BookDao.find(); String json=JSON.toJSONString(b); ` System.out.println(json);
将JSON字符串转换为对象
1. 引入JAR包 2. 在需要转换Java对象的位置, 编写如下代码: 类型 对象名=JSON.parseObject(JSON字符串, 类型.class); 或 List<类型> list=JSON.parseArray(JSON字符串,类型.class); 案例: String json = "{\"id\":1,\"name\":\"金苹果\",\"author\":\"李伟杰 \",\"info\":\"嘿嘿嘿嘿嘿嘿\",\"price\":198.0}"; Book book = JSON.parseObject(json, Book.class); System.out.println(book);
JSO支持的数据类型
- 数字(整数或浮点数)
- 逻辑值(true 或 false)
- 字符串(在双引号中)
- 数组(在方括号中)
- 函数
- 对象(在大括号中)
- null
JSON语法规则
大括号’{}’,
中括号’[]’,
逗号’,’,
冒号’:’,
双引号’“”’。
JSON基本语法与图例
1、Object(对象类型)
用{ }包含一系列无序的key–Value键值对表示,其中Key和Value之间用冒号分割,每个key-value之间用逗号分割
2、Array(数组类型)
3、组合型
JSON解析
- jar包下载地址 提取码:7fn6
- org.json官网下载
1.如果看到是{ }–>使用JSONObject
纯对象(Object)的解析{ }:
import org.json.JSONException;
import org.json.JSONObject;
/**
* JSON-->纯对象(Object)的解析
*
* 注:我们在eclipse里面操作JSON解析的时候需要第三方jar包的支持
* @author sKy°
* @date 2016-5-8
* @version 1.0
*/
public class Json01 {
public static void main(String[] args) {
// 编辑一个我们要解析的数据对象
// 根据JSON的官方定义,键,加"",值,如果是字符串,就加"",其他不加。
String json="{'name':'李书豪','age':24}";
try {
// 创建JSON解析对象(两条规则的体现:大括号用JSONObject,注意传入数据对象)
JSONObject obj = new JSONObject(json);
// obj.后面有各种数据类型,根据对象来选择使用的数据类型
String name = obj.getString("name");
// 同理如上,这里的age为Int类型,我们就用对应的类型进行解析
int age = obj.getInt("age");
// 最后输出到控制台
System.out.println(name+"<--->"+age);
} catch (JSONException e) {
e.printStackTrace();
}
}
}
纯数组(Array)的解析{ }:
import org.json.JSONArray;
import org.json.JSONException;
/**
* 对纯数组Aarry的解析
* @author sKy°
* @date 2016-5-8
* @version 1.0
*/
public class Json02 {
public static void main(String[] args) {
// 编辑一个我们要解析的数据对象
String json="['天津冷','北京暖','东京热','南京凉']";
try {
// 创建JSON解析对象(两条规则的体现:中括号用JSONArray,注意传入数据对象)
JSONArray jArray = new JSONArray(json);
// 取得数组长度
int length = jArray.length();
// 回想数组的取值的方式? --->for循环遍历数组--->得到值
for (int i = 0; i < length; i++) {
// 根据解析的数据类型使用该类型的get方法得到该值,打印输出
String string = jArray.getString(i);
System.out.print(string+",");
}
} catch (JSONException e) {
// TODO: handle exception
}
}
}
组合类型的解析(一):
/**
* 创建一个Person用于接收解析数据,封装对应字段
* @author sKy°
* @date 2016-5-8
* @version 1.0
*/
public class Person {
// 分析我们要解析的对象,根据解析对象的属性值去创建对应的属性值
// 根据分析我们所要解析的对象,两条属性 1.name(String类型) 2.是girlFrien(类类型,意味着还需要在类中去嵌套一个类(创建类部类也可))
// 封装字段
private String name;
private GirlFriend girlFriend; //类类型
// setter getter方法
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public GirlFriend getGirlFriend() {
return girlFriend;
}
public void setGirlFriend(GirlFriend girlFriend) {
this.girlFriend = girlFriend;
}
// toString方法用于控制台输出
@Override
public String toString() {
return "Person [name=" + name + ", girlFriend=" + girlFriend + "]";
}
}
// 为了方便咱们看,这里就直接在下面创建了一个GirlFriend这个类
class GirlFriend{
// 根据对象属性值,创建对应的值
private String name;
private int age;
// setter getter方法
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
// toString方法用于控制台输出
@Override
public String toString() {
return "GirlFriend [name=" + name + ", age=" + age + "]";
}
}
2.如果看到的[ ]–>使用JSONArray解析