一、Dom4j框架简介
注意:该博客是学习《黑马JavaEE12期》dom4j时所做的学习笔记。
DOM4j整合了DOM和SAX两种思想。读取XML时使用SAX的思想进行读取,又参照了DOM的思想,也在内存中创建了一个对象关系树。在该对象中也存在Document、Element、Attribute、Text等对象,我们学习的时候,参照之前我们学习的DOM树即可。
学习时,参照dom4j的官方文档,官方例子中有大量的例子,十分容易上手。
二、使用DOM4J操作XML文档
2.1 准备工作:导入Dom4j核心jar包,准备XML文档
新建名为students.xml的XML文档
<?xml version="1.0" encoding="utf-8" ?>
<students>
<student number="itcast_0001">
<name>tom</name>
<age>18</age>
<sex>male</sex>
</student>
<student number="itcast_0002">
<name>jerry</name>
<age>16</age>
<sex>female</sex>
</student>
</students>
2.2 打印XML文档
package cn.itcast.dom4j;
import java.io.File;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.io.SAXReader;
/**
* 使用Dom4j打印XML内容
*/
public class Demo1 {
public static void main(String[] args) {
SAXReader reader = new SAXReader();
try {
Document document = reader
.read(new File("src/students.xml"));
System.out.println(document.asXML());
} catch (DocumentException e) {
e.printStackTrace();
}
}
}
2、运行Demo1.java,控制台打印出如下内容
<?xmlversion="1.0" encoding="utf-8"?>
<students>
<studentnumber="itcast_0001">
<name>tom</name>
<age>18</age>
<sex>male</sex>
</student>
<studentnumber="itcast_0002">
<name>jerry</name>
<age>16</age>
<sex>female</sex>
</student>
</students>
2.3 查询出所有学生的所有信息
1、Demo2中的代码如下package cn.itcast.dom4j;
import java.io.File;
import java.util.Iterator;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
/**
* 查询出所有学生的所有信息
*/
public class Demo2 {
public static void main(String[] args) {
SAXReader reader = new SAXReader();
try {
Document document = reader
.read(new File("src/students.xml"));
//1、获得根元素
Element root = document.getRootElement();
//2、迭代根元素下的所有名叫student的子元素
for(Iterator<Element> it = root.elementIterator("student");
it.hasNext();) {
Element student = it.next();
//3、获得student元素的number属性
String number = student.attributeValue("number");
//4、student子元素的内容(name age sex)
String name = student.elementText("name");
String age = student.elementText("age");
String sex = student.elementText("sex");
System.out.println("当前学生的学号是:" + number
+ ",姓名是:" + name
+ ",年龄是:" + age
+ ",性别是:" + sex);
}
} catch (DocumentException e) {
e.printStackTrace();
}
}
}
2、运行上面的代码,控制台打印出如下的内容
当前学生的学号是:itcast_0001,姓名是:tom,年龄是:18,性别是:male
当前学生的学号是:itcast_0002,姓名是:jerry,年龄是:16,性别是:female
2.4 增加一个学生
1、具体代码如下
package cn.itcast.dom4j;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
/**
* 增加一个学生.
* jack itcast_0003 19 male
*/
public class Demo3 {
public static void main(String[] args) {
SAXReader reader = new SAXReader();
XMLWriter writer = null;
try {
Document document = reader
.read(new File("src/students.xml"));
//1、获得根元素
Element root = document.getRootElement();
//2、添加Element,添加number属性
Element studentEle = root.addElement("student")
.addAttribute("number", "itcast_0003");
//3、添加name age sex子元素并且添加子元素中的文本
studentEle.addElement("name").addText("杰克");
studentEle.addElement("age").addText("19");
studentEle.addElement("sex").addText("male");
//4、将document对象写到文件中
//创建格式化器
OutputFormat format = OutputFormat.createPrettyPrint();
//创建写入器
writer = new XMLWriter(
new FileWriter("src/students_copy.xml"), format);
//写入
writer.write(document);
} catch (DocumentException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (writer != null) {
//关闭资源
writer.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
2、运行上述代码,在src目录下生成students_copy.xml,内容如下
<?xml version="1.0" encoding="UTF-8"?>
<students>
<student number="itcast_0001">
<name>tom</name>
<age>18</age>
<sex>male</sex>
</student>
<student number="itcast_0002">
<name>jerry</name>
<age>16</age>
<sex>female</sex>
</student>
<student number="itcast_0003">
<name>杰克</name>
<age>19</age>
<sex>male</sex>
</student>
</students>
2.5 使用Xpath查找学生,删除学生
1、在工程中导入一个新的jar包
package cn.itcast.dom4j;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
/**
* 删除学号为itcast_0001的学生
*/
public class Demo4 {
public static void main(String[] args) {
SAXReader reader = new SAXReader();
XMLWriter writer = null;
try {
Document document = reader
.read(new File("src/students.xml"));
//1、获得根元素
Element root = document.getRootElement();
//使用XPath快速找到要找的元素
//定义XPath,查找number为itcast_0001的学生
//注意:[]中一定要有一对单引号,否则无法查找
String xpath = "//student[@number='itcast_0001']";
Element studentEle = (Element) document.selectSingleNode(xpath);
//执行删除操作
boolean isDeleteSuccess = studentEle.getParent().remove(studentEle);
System.out.println(isDeleteSuccess);
//会写
writer = new XMLWriter(new FileOutputStream
("src/students_copy.xml"), OutputFormat.createPrettyPrint());
writer.write(document);
//下面这个思路可以,但是效率太低
//2、获得所有学生元素
//3、遍历
//判断=>number属性是否为要删除的
//是 ==> 删除
//不是,则不删除
//4、回写
} catch (DocumentException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if(writer != null) {
try {
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
3、运行上面的例子,对比students.xml和students_copy.xml的内容
①students.xml中的内容
<?xml version="1.0" encoding="utf-8" ?>
<students>
<student number="itcast_0001">
<name>tom</name>
<age>18</age>
<sex>male</sex>
</student>
<student number="itcast_0002">
<name>jerry</name>
<age>16</age>
<sex>female</sex>
</student>
</students>
②student_copy.xml中的内容(number为itcast_0001的学生已经被删除)
<?xml version="1.0" encoding="UTF-8"?>
<students>
<student number="itcast_0002">
<name>jerry</name>
<age>16</age>
<sex>female</sex>
</student>
</students>
2.6 修改学生&XPATH表达式
package cn.itcast.dom4j;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
/**
* 修改学号为itcast_0001的学生
* rose 16 female
*/
public class Demo5 {
public static void main(String[] args) {
SAXReader reader = new SAXReader();
XMLWriter writer = null;
try {
Document document = reader
.read(new File("src/students.xml"));
//1、定义xpath表达式
String xpath = "//student[@number='itcast_0001']";
//2、使用xpath查找
Element studentEle = (Element) document.selectSingleNode(xpath);
//3、修改student元素的子元素的name,age,sex内容
studentEle.element("name").setText("rose");
studentEle.element("age").setText("16");
studentEle.element("sex").setText("female");
//回写
writer = new XMLWriter(new FileOutputStream("src/students_copy.xml")
, OutputFormat.createPrettyPrint());
writer.write(document);
} catch (DocumentException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
//关闭资源
if(writer != null) {
try {
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
2、对比students.xml与students_copy.xml中的内容
<?xml version="1.0" encoding="utf-8" ?>
<students>
<student number="itcast_0001">
<name>tom</name>
<age>18</age>
<sex>male</sex>
</student>
<student number="itcast_0002">
<name>jerry</name>
<age>16</age>
<sex>female</sex>
</student>
</students>
②students_copy.xml中的代码
<?xml version="1.0" encoding="UTF-8"?>
<students>
<student number="itcast_0001">
<name>rose</name>
<age>16</age>
<sex>female</sex>
</student>
<student number="itcast_0002">
<name>jerry</name>
<age>16</age>
<sex>female</sex>
</student>
</students>
2.7 使用elements()方法获取所有的子元素
package cn.itcast.dom4j;
import java.io.File;
import java.util.Iterator;
import java.util.List;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
/**
* 查询出所有学生的所有信息
*/
public class Demo2_2 {
public static void main(String[] args) {
SAXReader reader = new SAXReader();
try {
Document document = reader
.read(new File("src/students.xml"));
//1、获得根元素
Element root = document.getRootElement();
//2、获取根元素下所有名叫student的子元素
List<Element> list = root.elements("student");
for(Element student : list) {
//3、获得student元素的number属性
String number = student.attributeValue("number");
//4、student子元素的内容(name age sex)
String name = student.elementText("name");
String age = student.elementText("age");
String sex = student.elementText("sex");
System.out.println("当前学生的学号是:" + number
+ ",姓名是:" + name
+ ",年龄是:" + age
+ ",性别是:" + sex);
}
} catch (DocumentException e) {
e.printStackTrace();
}
}
}
2、运行上述例子,控制台打印的内容
当前学生的学号是:itcast_0001,姓名是:tom,年龄是:18,性别是:male
当前学生的学号是:itcast_0002,姓名是:jerry,年龄是:16,性别是:female