真的了解XML吗? - XML解析方式

前言

前面了解了XML的使用,语法,规范和DTD、Schema
真的了解XML吗? - XML 基础
继续对XML学习:XML解析


目录

  1. XML解析
  2. 解析方式
  3. 解析技术
  4. dom4j
    4.1. 一个dom4j案例
    4.2. dom4j操作详解
  5. XPath
    5.1. 一个XPath案例
  6. Jsoup
    6.1. Jsoup操作
    6.2. Jsoup中的对象
    6.3. 快速查询
  7. Jsoup和XPath
  8. 总结

XML解析

我们知道XML的作用是网络传输数据和存储数据

而解析就是:通过对XML文件的操作,将XML文件中的数据取出读取到内存中,然后就可以处理这些数据

操作XML文件:

  1. 将XML文件的数据读取到内存(解析)
  2. 将内存中的数据保存到XML文件(持久化)

当然XML主要还是解析,持久化很少用


解析方式

XML解析方式主流有三种:

  1. DOM(Document Object Model:文档对象模型):将标记语言文件一次性加载进内存,在内存中形成DOM树,所以速度较慢,占内存多
    DOM是W3C组织推荐的处理XML的方式

JS操作HTML文件就是DOM的思想

在这里插入图片描述DOM树:从根结点出发到各个子元素,类似与一个树形图
它可以对XML文件进行增删改查
有两个分支:jDom和dom4j

  1. SAX(Simple API for XML):它不是一次读取全部文件,而是读一行释放一行,基于事件驱动完成元素的解析,速度快,占内存少
    不是官方标准,但是几乎所有的XML解析器都支持
    只能进行查询
  2. Pull:Pull和SAX类似,都是轻量级的解析,是第三方开源的Java项目,在Android 内核中嵌入了Pull,只能进行解析(主要在移动端,不详细介绍)

解析技术

  1. JAXP:sun公司提供的解析器,支持DOM和SAX,但性能低、使用复杂,基本已经淘汰
  2. jdom:对DOM进行封装,简化了使用
  3. dom4j:在jdom的基础上进行了改进,在服务器端使用较多
  4. Jsoup:Java的HTML解析器,可直接解析某个URL地址、HTML文本内容。它提供了一套非常省力的API,可通过DOM,CSS以及类似于jQuery的操作方法来取出和操作数据(Jsoup主要还用来处理HTML的,但是同为标记语言,处理XML一样高效)

主要的解析器是dom4j和Jsoup,详细了解这两者


dom4j

百度百科:

dom4j是一个Java的XML API,是jdom的升级品,用来读写XML文件的。dom4j是一个十分优秀的JavaXML API,具有性能优异、功能强大和极其易使用的特点,它的性能超过sun公司官方的dom技术,同时它也是一个开放源代码的软件,可以在SourceForge上找到它。在IBM developerWorks上面还可以找到一篇文章,对主流的Java XML API进行的性能、功能和易用性的评测,所以可以知道dom4j无论在哪个方面都是非常出色的。如今可以看到越来越多的Java软件都在使用dom4j来读写XML,特别值得一提的是连Sun的JAXM也在用dom4j。这已经是必须使用的jar包, Hibernate也用它来读写配置文件

一个dom4j案例

  1. 首先将dom4j.jar包导入项目
    在这里插入图片描述

  2. 准备好已经存储了数据的xml文件
    两个book元素
    这个是符合我们自定义的Schema约束的xml文件(详情:真的了解XML吗? - XML 基础):
    books.xml:

<?xml version="1.0"?>

<books
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.W3Cshool.cn/xml books.xsd"
        xmlns="http://www.W3Cshool.cn/xml">

    <book sn="bookNum1">
        <name>时间简史</name>
        <author>霍金</author>
        <price>75</price>
    </book>
    <book sn="bookNum2">
        <name>三国演义</name>
        <author>罗贯中</author>
        <price>100</price>
    </book>


</books>

  1. 新建一个类,通过dom4j编程获得xml的数据
package com.company.Test;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import java.util.List;

public class Book {
    public static void main(String[] args) throws DocumentException {
        //创建SAXReader对象
        SAXReader saxReader = new SAXReader();
        //SAXReader对象负责读取xml文件,返回Document
        Document document = saxReader.read("src/com/company/xml/books.xml");
        System.out.println("doucument对象:"+document);
        //通过Document拿到根元素
        Element rootElement = document.getRootElement();
        System.out.println("根元素:"+rootElement);

        //通过根元素获得所有book元素,存放到列表中
        List<Element> books = rootElement.elements("book");
        //迭代所有的book,获得子标签
        for( Element book : books){

            Element name = book.element("name");
            System.out.println("name子元素:"+name);
            Element author = book.element("author");

            Element price = book.element("price");

            System.out.println("书籍信息: 书名:"+name.getText()+",作者:"+author.getText()+",价格:"+price.getText());

        }


    }
}

在这里插入图片描述
这个结果中包含着一些信息:

  1. 通过dom4j获得的是Document树,从根元素出发可以找到子元素
  2. 验证了Schema约束确实是有前缀的,前缀就是命名空间,只是在书写的时候省略了
  3. 得到的一个元素中会包含多种信息

dom4j操作详解

这是dom4j压缩包里的内容:
在这里插入图片描述
docs是第三方类库的学习文档
lib是dom4j需要依赖的jar包
src是dom4j源码

学习dom4j的操作当然要去学习文档看看了:进入docs文档-》index.html进入官网
在这里插入图片描述

Quick start是快速入门案例
当然,我们不需要去深入研究dom4j,了解一下API就够了

有哪些常用的API呢?

  1. 解析XML文档,有DOMReader和SAXReader两种,看名字就知道,一种是DOM解析方法,一种是SAX解析方法
SAXReader saxReader = new SAXReader();
DOMReader domReader = new DOMReader();
Document document = saxReader.read("src/com/company/xml/books.xml");

SAXReader对象中read方法可以传入各种参数
在这里插入图片描述

而DOMReader对象的read方法仅能传入Document(Document是一个接口,具体实现还是靠实现类):
也就是要先将xml文件加载进内存,然后获得该Document再解析
在这里插入图片描述

  1. 获取元素
    dom4j是将xml解析成树型,即要按照父子关系一步一步获得元素

先得到根元素:

Element rootElement = document.getRootElement();

再根据名字得到子元素:

List<Element> books = rootElement.elements("book");
Element name = book.element("name");

有两种方法:elements和element
当有多个子元素,可以使用elements方法得到一个列表List
当仅单个元素,可以用element方法获得Element (Element是一个接口)

  1. 操作元素
    XML中元素里会有属性、文本

可以通过Element进行操作

在这里插入图片描述
有很多方法,大致就是:获得各种信息(文本、属性、命名空间等);添加元素、属性等


XPath

XPath即为XML路径语言(XML Path Language),它是一种用来确定XML文档中某部分位置的语言

XPath 是在XML文档中查找信息的语言;通过元素和属性进行查找;简化了 Dom4j 查找节点的过程

一些语法:

语法意义
/books/book从根元素开始逐层找,以”/”开头
//name直接获取所有 name 元素对象,以“//”开头
//books/*获取所有 student 元素的所有子元素对象
//book[1]或 //book[last()]获取所有 book元素的第一个或最后一个
//book[@sn]获取所有带 sn 属性的 book元素对象
//book[@sn=“bookNum1”]获取 sn 等于 bookNum1 的 book元素对象

一个XPath案例

  1. 先导入包
    jaxen-1.1-beta-6.jar
    在这里插入图片描述

  2. 有xml文件,且要分清是否有命名空间

在这里插入图片描述
我这个就是有命名空间的

  1. 开始编程
package com.company.Test;

import com.company.Entity.Book;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.XPath;
import org.dom4j.io.SAXReader;

import java.util.HashMap;


public class BookXPath {
    public static void main(String[] args) throws DocumentException {
        SAXReader saxReader = new SAXReader();

        Document document = saxReader.read("src/com/company/xml/books.xml");
        System.out.println(document);
        //查询sn为bookNum1的书籍
        //如果xml没有命名空间,这种写法是对的
        //XPath xPath = document.createXPath("/books/book[@sn='bookNum1']");
        //如果xml有命名空间
        //先创建hashmap存放命名空间
        HashMap xmlmap = new HashMap();
        xmlmap.put("ns","http://www.W3Cshool.cn/xml");
        //创建xpth对象,并查找信息
        XPath path = document.createXPath("/ns:books/ns:book[@sn='bookNum1']");
        //将命名空间导入xpth
        path.setNamespaceURIs(xmlmap);
        //获取结点
        Element book = (Element)path.selectSingleNode(document);
        System.out.println(book);
        //根据元素名获得信息
        String name = book.elementText("name");
        String author = book.elementText("author");
        String price = book.elementText("price");
        //封装成一个book类
        Book aBook = new Book(name,author,Integer.parseInt(price));

        System.out.println(aBook);

    }
}

创建一个Entity包,创建一个Book实体类:

package com.company.Entity;

public class Book {
    private String name;
    private String author;
    private Integer price;

    public Book(String name, String author, Integer price) {
        this.name = name;
        this.author = author;
        this.price = price;
    }

    @Override
    public String toString() {
        return "book{" +
                "name='" + name + '\'' +
                ", author='" + author + '\'' +
                ", price=" + price +
                '}';
    }
}

在这里插入图片描述
如果XML没有命名空间,就可以很简单的直接在createXPath方法里写语法就可以
如果XML有命名空间,就需要设置一个HashMap,并将命名空间放入且命名一个key
注意语法(ns:book)

XPath path = document.createXPath("/ns:books/ns:book[@sn='bookNum1']");
path.setNamespaceURIs(xmlmap);

注意:map的命名空间的key别命名一些关键字如src等,这个会造成错误

通过Xpth可以较简单的获得元素
Xpath还可以在HTML中使用,不单单是XML


Jsoup

百度百科:

jsoup 是一款Java 的HTML解析器,可直接解析某个URL地址、HTML文本内容。它提供了一套非常省力的API,可通过DOM,CSS以及类似于jQuery的操作方法来取出和操作数据

它的主要功能:

  1. 从一个URL,文件或字符串中解析HTML、XML;
  2. 使用DOM或CSS选择器来查找、取出数据;
  3. 可操作HTML、XML元素、属性、文本

显然,Jsoup主要是用来操作HTML的,但是同为标记语言,一样可以操作XML

Jsoup操作

  1. 同样要导入包:jsoup-1.13.1.jar
    在这里插入图片描述

  2. 编写程序BookJsoup.class

package com.company.Test;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import java.io.File;
import java.io.IOException;


public class BookJsoup {
    public static void main(String[] args) throws IOException {
        //获取Document文档
        //获得student.xml的path
        String path = "src/com/company/xml/books.xml";
        //解析xml
        Document document = Jsoup.parse(new File(path), "UTF-8");

        //获取元素,Elements继承了ArrayList
        Elements books = document.getElementsByTag("book");
        System.out.println(books.size());
        //获得第一个book
        Element element = books.get(0);
        //获得所有文本信息
        String text = element.text();
        System.out.println("文本是:"+text);
        //获得name信息
        String name = element.getElementsByTag("name").text();
        System.out.println("第一本书的name:"+name);
    }
}

在这里插入图片描述

可以看出,Jsoup的操作类似JavaScript,先获得dom树,再通过getElementsByTag等等操作得到元素、文本

Jsoup中的对象

  1. Jsoup对象:解析器,类似与SAXReader,通过parse方法解析xml文件,返回document
  2. Document对象:就是dom树
  3. Elements对象:继承了ArrayList,类似于存储Element的列表,和dom4j中自定义的List< Element>
  4. Element对象:元素对象
  5. Node对象:结点对象

对JavaScript有基础的,可以看出Jsoup和JS是真的像
常用的方法也是类似:
在这里插入图片描述

快速查询

我们如果想要获得第一个book的name元素的值
需要通过: books->book->name->text

而Jsoup提供了简单的查询方法:选择器

package com.company.Test;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import java.io.File;
import java.io.IOException;


public class BookJsoup {
    public static void main(String[] args) throws IOException {
        //获取Document文档
        //获得student.xml的path
        String path = "src/com/company/xml/books.xml";
        //解析xml
        Document document = Jsoup.parse(new File(path), "UTF-8");
        //选择器
        Elements selectName = document.select("name");
        System.out.println(selectName);
    }
}

在这里插入图片描述

即可得到所有name元素


Jsoup和XPath

前面dom4j使用的快速查询的方法:XPath
一样可以和Jsoup一起使用(但是XPath与Jsoup关系并不大,XPath是操作dom树)

但是需要导入Jsoup的XPath包:JsoupXpath.jar
JsoupXpath下载地址
JsoupXpath包是一个中国人写的,随着版本的更替有了一些变化
在1.x的版本中,新建一个JXDocument对象是
import cn.wanghaomiao.xpath.model.JXDocument包
在这里插入图片描述

而在2.x版本已经更新了,JXDocument.create方法创建JXDocument
依赖也变成了import org.seimicrawler.xpath.JXDocument;
在这里插入图片描述

在这里插入图片描述

查询语法还是XPath的语法,不过要选择不同的查询方法
sel;selN;selNOne;SelOne
在这里插入图片描述

具体的用法可以看作者的github


总结

  1. XML的解析技术有:DOM;SAX;Pull
  2. 其中DOM是将Document全部加载进内存,形成dom树,可以进行增删改查,缺点是占用内存大,速度慢
  3. SAX是基于事件驱动,将Document一行一行的读取,释放;只能进行查询操作,占用内存小(仅一行),速度快
  4. Pull类似与SAX,使用与移动端,Android 内嵌了Pull
  5. 常用的解析器有dom4j和Jsoup
  6. 通过XPath可以进行快速查询
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值