七、XML和Json

一、XML

请看我的另一篇博文

二、XML解析的四种方式

一、SAX解析

  1. SAX解析
    解析方式是事件驱动机制 !
    SAX解析器, 逐行读取XML文件解析 , 每当解析到一个标签的开始/结束/内容/属性时,触发事件.
    我们可以编写程序在这些事件发生时, 进行相应的处理.
    优点:
    分析能够立即开始,而不是等待所有的数据被处理
    逐行加载,节省内存.有助于解析大于系统内存的文档
    有时不必解析整个文档,它可以在某个条件得到满足时停止解析.
    缺点:
  2. 单向解析,无法定位文档层次,无法同时访问同一文档的不同部分数据(因为逐
    行解析, 当解析第n行是, 第n-1行已经被释放了, 无法在进行操作了).
  3. 无法得知事件发生时元素的层次, 只能自己维护节点的父/子关系.
  4. 只读解析方式, 无法修改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解析

  1. 引入jar文件 dom4j.jar
  2. 创建一个指向XML文件的输入流
    FileInputStream fis = new FileInputStream(“xml文件的地址”);
  3. 创建一个XML读取工具对象
    SAXReader sr = new SAXReader();
  4. 使用读取工具对象, 读取XML文档的输入流 , 并得到文档对象
    Document doc = sr.read(fis);
  5. 通过文档对象, 获取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

  1. 通过文档对象, 获取XML文档中的根元素对象
    Element root = doc.getRootElement();
  2. 添加根节点
    Element root = doc.addElement(“根节点名称”);

元素对象 Element

  1. 获取节点名称
    String getName();
  2. 获取节点内容
    String getText();
  3. 设置节点内容
    String setText();
  4. 根据子节点的名称 , 获取匹配名称的第一个子节点对象.
    Element element(String 子节点名称);
  5. 获取所有的子节点对象
    List < Element> elements();
  6. 获取节点的属性值
    String attributeValue(String 属性名称);
  7. 获取子节点的内容
    String elementText(String 子节点名称);
  8. 添加子节点
    Element addElement(String 子节点名称);
  9. 添加属性
    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表达式”); 查询多个节点对象

通过路径快速的查找一个或一组元素
路径表达式:

  1. / : 从根节点开始查找
  2. // : 从发起查找的节点位置 查找后代节点 ***
  3. . : 查找当前节点
  4. … : 查找父节点
  5. @ : 选择属性. *
    属性使用方式:
    [@属性名=‘值’]
    [@属性名>‘值’]
    [@属性名<‘值’]
    [@属性名!=‘值’]
    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

学习链接1
学习链接2

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支持的数据类型

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

JSON语法规则

大括号’{}’,
中括号’[]’,
逗号’,’,
冒号’:’,
双引号’“”’。

JSON基本语法与图例

1、Object(对象类型)
用{ }包含一系列无序的key–Value键值对表示,其中Key和Value之间用冒号分割,每个key-value之间用逗号分割
在这里插入图片描述
2、Array(数组类型)
在这里插入图片描述
3、组合型
在这里插入图片描述

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解析

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值