由于dom4j在获取某个节点时都得一级一级往下获,很不方便。
由于XPath表达式,获取某个节点很方便直观,所以就要由dom4j API 结合XPath表达式来获取节点,然后对节点进行某些操作。
- XPath快速入门,查看官方帮助文档:XPathTutorial.chm
- dom4j API 与XPath的结合,要看dom4j的docs里面的Quick Start:Powerful Navigation with XPath
- 获取多个节点:Listlist = document. selectNodes ("//foo/bar");
- 获取单个节点:Nodenode = document. selectSingleNode ("//foo/bar/author");
- 获取多个节点:Listlist = document. selectNodes ("//foo/bar");
- 获取单个节点:Nodenode = document. selectSingleNode ("//foo/bar/author");
创建XPath需要jaxen.jar包的支持。如没有导入可能会报错:java.lang.NoClassDefFoundError: org/jaxen/JaxenException
练习一:
book.xml
<?xml version="1.0" encoding="UTF-8"?>
<书架>
<书 name="yyyYYY">
<书名>Java就业培训教程</书名>
<售价>999</售价>
<售价>999</售价>
<作者>张孝祥</作者>
<售价>20元</售价>
<售价>20元</售价>
</书>
<书>
<书名>JavaScript网页开发</书名>
<作者>张孝祥</作者>
<售价>28.00元</售价>
</书>
</书架>
//获取第二个书名的值
@Test
public void findwithXpath() throws DocumentException{
SAXReader reader = new SAXReader();
Document document = reader.read("src/book.xml");
//获取第二个书名的值
Element ele = (Element)document.selectNodes("//书名").get(1);
System.out.println(ele.getText());
}
练习二:
users.xml
<?xml version="1.0" encoding="UTF-8"?>
<users>
<user username="lisi" password="123"></user>
<user username="wanghong" password="123"></user>
<user username="hehe" password="123"></user>
</users>
//用户登录
@Test
public void login() throws DocumentException{
SAXReader reader = new SAXReader();
Document document = reader.read("src/users.xml");
String username = "lisi";
String password = "123";
Node node = document.selectSingleNode("//user[@username='"+username+"' and @password='"+password+"']");
if(node != null){
System.out.println("登录成功!");
}else{
System.out.println("用户名或密码错误......");
}
}
练习三:用dom4j做学生成绩管理系统的重构
需求分析:
1、以如下格式的exam.xml文件为例
exam.xml
<?xml version="1.0" encoding="UTF-8"?>
<exam>
<student examid="222" idcard="111">
<name>张三</name>
<location>沈阳</location>
<grade>89.00</grade>
</student>
<student examid="444" idcard="333">
<name>李四</name>
<location>大连</location>
<grade>97.00</grade>
</student>
</exam>
2、编程实现如下功能
3、实现学生信息的添加
4、实现学生信息的查询
5、实现学生的删除功能
模块流程图:
添加数据:
查询数据:
开发顺序:
先写javabean,再写Dao用到的工具类、 Dao ,最后写界面层Main。
不同模块的程序,要放在不同的包里:
- 实体javabean:放在domain包。
- Dao:放在dao包。dao操作xml文档必定会有重复代码:得到document、更新xml文档。将他们抽取到工具类XmlUtils里。
- 工具类XmlUtils:放在utils工具包中。
- 界面Main:放在main包。
程序源码:
package cn.mengmei.domain;
public class Student {
private String idcard;
private String examid;
private String name;
private String location;
private double grade;
public String getIdcard() {
return idcard;
}
public void setIdcard(String idcard) {
this.idcard = idcard;
}
public String getExamid() {
return examid;
}
public void setExamid(String examid) {
this.examid = examid;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getLocation() {
return location;
}
public void setLocation(String location) {
this.location = location;
}
public double getGrade() {
return grade;
}
public void setGrade(double grade) {
this.grade = grade;
}
}
package cn.mengmei.utils;
import java.io.FileOutputStream;
import java.io.IOException;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
public class XMLUtils {
public static Document getDocument() throws DocumentException{
SAXReader reader = new SAXReader();
Document document = reader.read("src/exam.xml");
return document;
}
public static void write2XML(Document document) throws IOException{
OutputFormat format = OutputFormat.createPrettyPrint();
format.setEncoding("UTF-8");
XMLWriter writer = new XMLWriter(new FileOutputStream("src/exam.xml"),format);
writer.write(document);
writer.close();
}
}
package cn.mengmei.dao;
import java.util.Iterator;
import java.util.List;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.Node;
import cn.mengmei.domain.Student;
import cn.mengmei.utils.XMLUtils;
public class StudentDao {
public void add(Student student){
try {
Document document = XMLUtils.getDocument();
Element root = document.getRootElement();
Element stuNode = root.addElement("student");
stuNode.addAttribute("idcard", student.getIdcard());
stuNode.addAttribute("examid", student.getExamid());
stuNode.addElement("name").setText(student.getName());
stuNode.addElement("location").setText(student.getLocation());
stuNode.addElement("grade").setText(student.getGrade()+"");
XMLUtils.write2XML(document);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public void delete(String name){
try {
Document document = XMLUtils.getDocument();
List<Node> nameList = document.selectNodes("//name");
for(Iterator<Node> it=nameList.iterator(); it.hasNext(); ){
Node nameNode = it.next();
if(nameNode.getText().equals(name)){
Node stuNode = nameNode.getParent();
stuNode.getParent().remove(stuNode);
XMLUtils.write2XML(document);
return;
}
}
throw new RuntimeException("------对不起,没有查到此学生!-----");
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public Student read(String examid){
try{
Document document = XMLUtils.getDocument();
Element stuNode = (Element)document.selectSingleNode("//student[@examid='"+examid+"']");
if(stuNode != null){
Student student = new Student();
student.setIdcard(stuNode.attributeValue("idcard"));
student.setExamid(stuNode.attributeValue("examid"));
student.setName(stuNode.elementText("name"));
student.setLocation(stuNode.elementText("location"));
student.setGrade(Double.parseDouble(stuNode.elementText("grade")));
return student;
}
return null;
}catch(Exception e){
throw new RuntimeException(e);
}
}
}
package cn.mengmei.main;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import cn.mengmei.dao.StudentDao;
import cn.mengmei.domain.Student;
public class Main {
public static void main(String[] args) {
System.out.println("添加用户:(a) 删除用户:(b) 查询成绩:(c)");
System.out.print("请输入操作类型:");
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
String item = null;
try {
item = reader.readLine();
} catch (IOException e) {
System.out.println("-----------类型读取失败!---------");
}
Student student = null;
String idcard = null;
String examid = null;
String name = null;
String location = null;
String grade = null;
StudentDao dao = null;
switch (item) {
case "a":
try{
System.out.print("请输入学生姓名:");
name = reader.readLine();
System.out.print("请输入学生身份证号:");
idcard = reader.readLine();
System.out.print("请输入学生准考证号:");
examid = reader.readLine();
System.out.print("请输入学生所在地:");
location = reader.readLine();
System.out.print("请输入学生成绩:");
grade = reader.readLine();
student = new Student();
student.setName(name);
student.setIdcard(idcard);
student.setExamid(examid);
student.setLocation(location);
student.setGrade(Double.parseDouble(grade));
dao = new StudentDao();
dao.add(student);
System.out.println("--------添加数据成功--------");
}catch(Exception e){
System.out.println("---------对不起,添加失败!---------");
}
break;
case "b":
try{
System.out.print("请输入要删除的学生姓名:");
name = reader.readLine();
dao = new StudentDao();
dao.delete(name);
System.out.println("------已成功删除学生信息------");
}catch(Exception e){
System.out.println(e.getMessage());
}
break;
case "c":
try {
System.out.print("请输入要查询的学生准考证号:");
examid = reader.readLine();
dao = new StudentDao();
student = dao.read(examid);
if(student != null){
System.out.println("姓名:"+student.getName());
System.out.println("身份证号:"+student.getIdcard());
System.out.println("准考证号:"+student.getExamid());
System.out.println("所在地:"+student.getLocation());
System.out.println("成绩:"+student.getGrade());
}else{
System.out.println("-----对不起,你要查询的学生信息不存在!-----");
}
} catch (Exception e) {
System.out.println("------对不起,查询失败!------");
}
break;
default:
System.out.println("------对不起,不支持此种操作类型!------");
break;
}
}
}