欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Java Web基础入门第五讲 XML语言——DOM4J实现对XML文档的CRUD操作

程序员文章站 2024-01-11 17:13:22
...

DOM4J简介

DOM4J是一个简单、灵活的开放源代码的库。DOM4J是由早期开发JDOM的人分离出来而后独立开发的。与JDOM不同的是,DOM4J使用接口和抽象基类,虽然DOM4J的API相对要复杂一些,但它提供了比JDOM更好的灵活性。它是一个非常优秀的Java XML API,具有性能优异、功能强大和极易使用的特点。现在很多软件采用DOM4J,例如Hibernate,包括SUN公司自己的JAXM也用了DOM4J。不过,初学者要注意的一点是使用DOM4J开发,需下载DOM4J相应的jar文件。

DOM4J解析XML文档

DOM4J的使用

大家可从网上下载dom4j-1.6.1.zip压缩包,解压开之后,发现几个目录和一个jar文件,jar文件是必须的文件,如图:
Java Web基础入门第五讲 XML语言——DOM4J实现对XML文档的CRUD操作
打开docs目录,单击index.html,如图:
Java Web基础入门第五讲 XML语言——DOM4J实现对XML文档的CRUD操作
Quick start是快速入门超链接,我们主要参考这里的代码完成对DOM4J的认识,并完成CRUD的操作。Javadoc(1.6.1)是DOM4J的帮助文档,需要查找相关信息的时候主要参考这里。
使用DOM4J最大的好处就是能够大大简化对XML文档的操作。但应当注意,导包的时候应当导入的包是DOM4J的包,而不是原来的包了,比如:Document对象应当导入的包名为org.dom4j.Document。

Document对象

DOM4J中,获得Document对象的方式有三种:

  1. 读取XML文件,获得Document对象;
    Java Web基础入门第五讲 XML语言——DOM4J实现对XML文档的CRUD操作
  2. 解析XML形式的文本,得到Document对象;
    Java Web基础入门第五讲 XML语言——DOM4J实现对XML文档的CRUD操作
  3. 主动创建Document对象。
    Java Web基础入门第五讲 XML语言——DOM4J实现对XML文档的CRUD操作

节点对象

Java Web基础入门第五讲 XML语言——DOM4J实现对XML文档的CRUD操作

节点对象属性

Java Web基础入门第五讲 XML语言——DOM4J实现对XML文档的CRUD操作

DOM4J在指定位置插入节点

Java Web基础入门第五讲 XML语言——DOM4J实现对XML文档的CRUD操作

字符串与XML之间的转换

如果要将字符串转化为XML,那么可以这样做:
Java Web基础入门第五讲 XML语言——DOM4J实现对XML文档的CRUD操作
又想将文档或节点的XML转化为字符串,则可这样做:
Java Web基础入门第五讲 XML语言——DOM4J实现对XML文档的CRUD操作

CRUD操作

新建一个Java项目,对项目名称右键单击,新建目录lib,将相关的jar文件复制到该目录中,选中所有的jar文件,右键→build path→add to buildpath。然后,再准备一个book.xml文档,内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<书架>
	<>
		<书名>Java就业培训教程</书名>
		<作者>张孝祥</作者>
		<售价>109元</售价>
	</>
	<>
		<书名 name="xxxx">JavaScript网页开发</书名>
		<作者>黎明</作者>
		<售价>28.00元</售价>
	</>
</书架>

接下来,就要使用DOM4J实现对以上XML文档的CRUD操作了。

读取

需求:读取book.xml文档中的第二本书的书名,即JavaScript网页开发

public class Demo1 {
	
	//读取XML文档第二本书的书名:<书名>JavaScript网页开发</书名>
	@Test
	public void read() throws DocumentException {
		SAXReader reader = new SAXReader();
        Document document = reader.read(new File("src/book.xml"));
        
        //得到根节点(即书架)
        Element root = document.getRootElement();
//      root.element("书");//得到的是第一本书
        Element book = (Element) root.elements("书").get(1);
        String value = book.element("书名").getText();
        System.out.println(value);
	}

}

再来看一个需求:读取book.xml文档第二本书的属性值,即name="xxxx"

public class Demo1 {
	
	//读取XML文档第二本书的属性:<书名 name="xxxx">JavaScript网页开发</书名>
	@Test
	public void readAttr() throws DocumentException {
		SAXReader reader = new SAXReader();
		Document document = reader.read(new File("src/book.xml"));
		
		//得到根节点(即书架)
		Element root = document.getRootElement();
//      root.element("书");//得到的是第一本书
		Element book = (Element) root.elements("书").get(1);
		
		/*
		 * 第一种方式,稍显麻烦
		 */
//		String value = book.element("书名").attribute("name").getValue();
		
		/*
		 * 第二种方式,略简单
		 */
		String value = book.element("书名").attributeValue("name");
		System.out.println(value);
	}

}

添加

需求:在第一本书中添加一个新的售价,即<售价>209元</售价>

public class Demo1 {
	
	//在第一本书上添加一个新的售价:<售价>209元</售价>
	@Test
	public void add() throws Exception {
		SAXReader reader = new SAXReader();
		//不管你这个XML文档是什么编码,它一读到内存里面去,Document就产生了UTF-8码表
		Document document = reader.read(new File("src/book.xml"));
		
		Element book = document.getRootElement().element("书");
		book.addElement("售价").setText("209元");
		
		OutputFormat format = OutputFormat.createPrettyPrint();
		format.setEncoding("UTF-8");//xml文档是什么编码,就给格式化输出器指定一个码表(例如GBK),将Document按照GBK码表写出去。
		XMLWriter writer = new XMLWriter(new FileOutputStream("src/book.xml"), format);
		
		//把更新后的Document写回到xml文档里面去
        writer.write(document);
        writer.close();
	}

}

添加之后,book.xml内容如下:
Java Web基础入门第五讲 XML语言——DOM4J实现对XML文档的CRUD操作
如果我们想在第一本书的指定位置上添加一个新的售价,即<售价>209元</售价>,那么又该怎么做呢?这就需要更改保存了所有孩子的List集合的顺序。

public class Demo1 {
	
	//在第一本书的指定位置上添加一个新的售价:<售价>209元</售价>,需要更改保存了所有孩子的List集合的顺序
	@Test
	public void add2() throws Exception {
		SAXReader reader = new SAXReader();
		//不管你这个XML文档是什么编码,它一读到内存里面去,Document就产生了UTF-8码表
		Document document = reader.read(new File("src/book.xml"));
		
		Element book = document.getRootElement().element("书");
		List list = book.elements();//[书名,作者,售价]
		
		Element price = DocumentHelper.createElement("售价");
		price.setText("309元");
		list.add(2, price);//往指定位置上添加一个元素
		
		OutputFormat format = OutputFormat.createPrettyPrint();
		format.setEncoding("UTF-8");
		XMLWriter writer = new XMLWriter(new FileOutputStream("src/book.xml"), format);
		writer.write(document);
        writer.close();
	}

}

添加之后,book.xml内容如下:
Java Web基础入门第五讲 XML语言——DOM4J实现对XML文档的CRUD操作

删除

如果我们想要删除上面添加的售价节点,那么可以这样做:

public class Demo1 {
	
	//删除上面添加的售价节点
	@Test
	public void delete() throws Exception {
		SAXReader reader = new SAXReader();
		Document document = reader.read(new File("src/book.xml"));
		
		Element price = document.getRootElement().element("书").element("售价");
		price.getParent().remove(price);
		
		OutputFormat format = OutputFormat.createPrettyPrint();
		format.setEncoding("UTF-8");
		XMLWriter writer = new XMLWriter(new FileOutputStream("src/book.xml"), format);
		writer.write(document);
        writer.close();
	}

}

修改

需求:将第二本书的作者——“黎活明”修改为“黎明”。

public class Demo1 {
	
	//更新
	@Test
	public void update() throws Exception {
		SAXReader reader = new SAXReader();
		Document document = reader.read(new File("src/book.xml"));
		
		Element book = (Element) document.getRootElement().elements("书").get(1);
		book.element("作者").setText("黎明");
		
		
		OutputFormat format = OutputFormat.createPrettyPrint();
		format.setEncoding("UTF-8");
		XMLWriter writer = new XMLWriter(new FileOutputStream("src/book.xml"), format);
		writer.write(document);
        writer.close();
	}

}

DOM4J使用XPath技术提取XML文档数据

XPath简介

使用XPath可以快速精确定位指定的节点,以实现对XML文件的CRUD操作。

XPath语法

为了学习XPath语法,可去网上下载一个“XPath帮助文档”,以便于查看语法等详细信息,最好是那种有很多实例的那种。这里就不专门赘述了。

使用XPath、DOM4J解析XML文档

案例一

有这样一个book.xml文档:

<?xml version="1.0" encoding="UTF-8"?>
<书架>
	<>
		<书名>Java就业培训教程</书名>
		<作者>张孝祥</作者>
		<售价>109元</售价>
	</>
	<>
		<书名 name="xxxx">JavaScript网页开发</书名>
		<作者>黎明</作者>
		<售价>28.00元</售价>
	</>
</书架>

想要查找到<作者>张孝祥</作者>元素,并将其文本内容显示出来,那么可以这样子做:

package cn.liayun.dom4j;

import java.io.File;

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

public class Demo2 {

	/*
	 * 应用XPath提取xml文档中的数据
	 */
	public static void main(String[] args) throws Exception {
		SAXReader reader = new SAXReader();
        Document document = reader.read(new File("src/book.xml"));
        
        String value = document.selectSingleNode("//作者").getText();
        System.out.println(value);
	}

}

注意,在使用XPath解析XML文档时,dom4j-1.6.1.jar依赖的jar包(jaxen-1.1-beta-6.jar)如果没有导入进来,那么就会报如下异常:

java.lang.NoClassDefFoundError: org/jaxen/NamespaceContext

所以应当将jaxen-1.1-beta-6.jar包加到构建路径中来。

案例二

有这样一个users.xml文档:

<?xml version="1.0" encoding="UTF-8"?>
<users>
	<user id="121" username="aaa" password="123" email="aaa@qq.com" />
	<user id="122" username="bbb" password="123" email="aaa@qq.com" />
</users>

如果我们想要判断用户是否登录成功,应该怎么做呢?很简单啦!只须查找users.xml文档中是否有和用户相匹配的用户名和密码。

package cn.liayun.dom4j;

import java.io.File;

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

public class Demo3 {
	
	/**
	 * 查找users.xml文档中是否有和用户相匹配的用户名和密码
	 * @param args
	 * @throws DocumentException 
	 */
	public static void main(String[] args) throws DocumentException {
		String username = "aaa";
		String password = "123";
		
		//检测xml文档中是否有匹配的用户名和密码
		SAXReader reader = new SAXReader();
        Document document = reader.read(new File("src/cn/liayun/dom4j/users.xml"));
        
        Node node = document.selectSingleNode("//user[@username='" + username + "' and @password='" + password + "']");
        if (node == null) {
			System.out.println("用户名或密码错误!!");
		} else {
			System.out.println("登录成功");
		}
        
	}

}

很明显,代码量大大减少了,使用XPath解析XML文件比起单纯使用DOM4J解析XML文件效率更高,实用性很强,应当重点注意,尽量使用该方法解析XML文件。