使用Dom4j解析XML文档

1.Dom4j简介

  • Dom4j是一个简单、灵活的开放源代码的库。Dom4j是由早期开发JDOM的人分离出来而后独立开发的。与JDOM不同的是,dom4j使用接口和抽象基类,虽然Dom4j的API相对要复杂一些,但它提供了比JDOM更好的灵活性。
  • Dom4j是一个非常优秀的Java XML的API,具有性能优异、功能强大和极易使用的特点。现在很多软件采用的Dom4j,例如Hibernate,包括sun公司自的JAXM也用了Dom4j。
  • 使用Dom4j开发,需下载dom4j相应的jar文件。可前往https://dom4j.github.io/进行相应版本的下载,在这里LZ选择了dom4j-2.1.0进行了下载。

2.使用Dom4j获取Document对象

在Dom4j中获取Document对象的方式有三种:

    //1.读取XML文件,获得document对象
    SAXReader reader = new SAXReader();
    Document document = reader.read("src/book.xml");

    //2.解析XML形式的文本,得到document对象.
    String text = "<书名></书名>";
    Document document = DocumentHelper.parseText(text);

    //3.主动创建document对象.
    Document document = DocumentHelper.createDocument();
    //创建根节点
    Element root = document.addElement("members");

3.使用Dom4j对xml文档进行基本操作

xml代码示例:

<?xml version="1.0" encoding="UTF-8"?>

<书架> 
  <> 
    <书名 name="jxs">大话数据结构</书名>  
    <作者>程杰</作者>  
    <售价>38.00</售价>
  </>  
  <> 
    <书名>MySQL必知必会</书名>  
    <作者>Ben Forta</作者>  
    <售价>23.00</售价> 
  </> 
</书架>

基本操作代码示例:

package dom4j;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
import org.junit.Test;

import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;

/**
 * Created by jiangxs on 2017/10/11.
 * 使用dom4j对xml文档进行解析
 * CRUD
 */
public class Foo {

    /**
     * 遍历xml文档中的所有标签
     * */
    @Test
    public void listTag() throws DocumentException {
        SAXReader reader = new SAXReader();
        Document document = reader.read("src/book.xml");
        Element element = document.getRootElement();
        list(element);
    }

    public void list(Element element){
        System.out.println(element.getName());
        List<Element> list = element.elements();
        for (Element child : list){
            list(child);
        }
    }

    /**
     * 获取<书名 name="jxs">大话数据结构</书名>节点内容
     * */
    @Test
    public void test1() throws DocumentException {
        SAXReader reader = new SAXReader();
        Document document = reader.read("src/book.xml");
        String text = document.getRootElement().element("书").element("书名").getText();
        System.out.println(text);
    }

    /**
     * 获取<书名 name="jxs">大话数据结构</书名>节点内容
     * */
    @Test
    public void test2() throws DocumentException {
        SAXReader reader = new SAXReader();
        Document document = reader.read("src/book.xml");
        Element bookName = document.getRootElement().element("书").element("书名");
        System.out.println(bookName.attributeValue("name"));
    }

    /**
     * 向xml文档中添加一个售价节点
     * */
    @Test
    public void test3() throws DocumentException, IOException {
        SAXReader reader = new SAXReader();
        Document document = reader.read("src/book.xml");
        //创建需要添加的节点
        Element element = DocumentHelper.createElement("售价");
        element.setText("39.00");
        //把节点挂到书下
        document.getRootElement().element("书").add(element);
        //使用pretty使生成的新节点按格式排列
        OutputFormat format = OutputFormat.createPrettyPrint();
        format.setEncoding("UTF-8");

        //把更新内容写到xml下
        //使用字节流不会由于两边格式不一致而出现乱码
        XMLWriter writer = new XMLWriter(new FileOutputStream("src/book.xml"),format);
        writer.write(document);
        writer.close();
    }

    /**
     * 向xml文档中指定位置删除一个售价节点
     * */
    @Test
    public void test5() throws DocumentException, IOException {
        SAXReader reader = new SAXReader();
        Document document = reader.read("src/book.xml");

        //选择需要删除的节点
        Element element = document.getRootElement().element("书").elements("售价").get(1);
        element.getParent().remove(element);

        //刷新
        OutputFormat format = OutputFormat.createPrettyPrint();
        format.setEncoding("UTF-8");
        XMLWriter writer = new XMLWriter(new FileOutputStream("src/book.xml"),format);
        writer.write(document);
        writer.close();
    }

    /**
     * 向xml文档中指定位置修改一个售价节点
     * */
    @Test
    public void test6() throws DocumentException, IOException {
        SAXReader reader = new SAXReader();
        Document document = reader.read("src/book.xml");

        //选择需要修改的节点进行修改
        Element element = document.getRootElement().element("书").elements("售价").get(1);
        element.setText("55.00");

        //刷新
        OutputFormat format = OutputFormat.createPrettyPrint();
        format.setEncoding("UTF-8");
        XMLWriter writer = new XMLWriter(new FileOutputStream("src/book.xml"),format);
        writer.write(document);
        writer.close();
    }
}

4.XPath的基本语法

下面的语法基于该xml文档

<?xml version="1.0" encoding="UTF-8"?>

<书架> 
  <>
    <书名 name="jxs">大话数据结构</书名>
    <作者>程杰</作者>  
    <售价>88.00</售价>  
    <售价>55.00</售价> 
  </>  
  <> 
    <书名 name="sxj">MySQL必知必会</书名>  
    <作者>Ben Forta</作者>  
    <售价>23.00</售价> 
  </> 
</书架>
选取节点
表达式描述
nodename选取此节点的所有子节点
/从根节点选取
//从匹配选择的当前节点选择文档中的节点,而不考虑它们的位置
.选取当前节点
..选取当前节点的父节点
@选取属性

应用上述表格

路径表达式结果
书架选取”书架”元素的所有子节点
/书架选取根元素”书架”(假如路径起始于正斜杠(/),则此路径始终代表到某元素的绝对路径)
书架/书选取书架的子元素所有书元素
//书选取所有书子元素,而不管它们在文档中的位置
书架//书选择属于书架元素的后代的所有书元素,而不管它们位于书架之下的什么位置
@name选取名为name的所有属性
谓语(Predicates)

谓语用来查找某个特定的节点或者包含某个指定的值的节点。
谓语被嵌在方括号中。
在下面的表格中,我们列出了带有谓语的一些路径表达式,以及表达式的结果:

路径表达式结果
/书架/书[1]选取属于 书架 子元素的第一个 书 元素
/书架/书[last()]选取属于 书架 子元素的最后一个 书 元素
/书架/[last()-1]选取属于 书架 子元素的倒数第二个 书 元素
/书架/书[position()<3]选取最前面的两个属于 书架 元素的子元素的 书 元素。
//书名[@name]选取所有拥有名为 name 的属性的 书名 元素
//书名[@name=’jxs’]选取所有 书名 元素,且这些元素拥有值为 jxs 的 name 属性。
/书架/书[售价>30]选取 书架 元素的所有 书 元素,且其中的 售价 元素的值须大于 30.00。
/书架/书[售价>30.00]/书名选取 书架 元素中的 书 元素的所有 书名 元素,且其中的 售价 元素的值须大于 30.00。
选取未知节点

XPath 通配符可用来选取未知的 XML 元素。

通配符描述
*匹配任何元素节点
@*匹配任何属性节点
node()匹配任何类型的节点

下面表格列出了一些路径表达式,以及这些表达式的结果:

路径表达式结果
/书架/*选取 书 元素的所有子元素
//*获取文档中的所有元素
//title[@*]选取所有带属性的title元素
选取若干路径

通过在路径表达式中使用”|”运算符可以选取若干个路径。

XPath小例子

示例程序1:
改代码的xml文件用的上述xml文件

package dom4j;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;
import org.junit.Test;

/**
 * Created by jiangxs on 2017/10/16.
 * 在dom4j中使用XPath
 */
public class XpathDemo {

    @Test
    public void test1() throws DocumentException {
        SAXReader reader = new SAXReader();
        Document document = reader.read("src/book.xml");

        //选择要查找的内容
        Element element = (Element) document.selectNodes("//作者").get(0);
        System.out.println(element.getText());
    }
}

示例程序2:

<?xml version="1.0" encoding="UTF-8" ?>
<users>
    <user username="张三" password="123"></user>
    <user username="李四" password="123"></user>
    <user username="王五" password="123"></user>
    <user username="ZhaoLiu" password="123"></user>
    <user username="jxs" password="12345678"></user>
</users>
package dom4j;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;
import org.junit.Test;

/**
 * Created by jiangxs on 2017/10/16.
 * 在dom4j中使用XPath
 */
public class XpathDemo {

    @Test
    public void test2() throws DocumentException {
        String name = "王五";
        String password = "123";

        SAXReader reader = new SAXReader();
        Document document = reader.read("src/userlogging.xml");

        Node node = document.selectSingleNode("//user[@username='"+name+"' and @password='"+password+"']");
        if (node != null)
            System.out.println("登录成功!欢迎您!");
        else
            System.out.println("登录名或密码错误,登录失败,请重试!");
    }
}

示例程序2演示结果:

登录成功!欢迎您!

Process finished with exit code 0
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值