dom4j
学习 了dom4j,通过一个小项目巩固一下。
- 利用xml文件来存储图书信息,用dom4j来操作文件对象,完成一个控制台的图书管理小程序
- 需要实现的功能有图书的查询,修改,删除和添加
程序比较简单,大致划分一下结构即可
- 对应图书信息的实体类Book
- 操作存储图书信息xml文件的内容
- 控制流程的
实现
我们先看book
package sxnd.book;
public class Book {
//增加图书,是根据id给bookId
public static int id;
private String bookId;
/**
* 图书名
*/
private String bookName;
/**
* 作者
*/
private String bookAuthor;
/**
* 出版社
*/
private String publish;
public Book(String bookId, String bookName, String bookAuthor, String publish) {
super();
this.bookId = bookId;
this.bookName = bookName;
this.bookAuthor = bookAuthor;
this.publish = publish;
}
//重写
public String toString() {
return bookName + "\t 作者:" + bookAuthor + "\t 出版社:" + publish;
}
//getXxx和setXxx方法
//...
}
对应的xml文件
<?xml version="1.0" encoding="UTF-8"?>
<books>
<book>
<bookId>1</bookId>
<bookName>老人与海1</bookName>
<bookAuthor>海明威1</bookAuthor>
<publish>机械工业出版社2016版</publish>
</book>
<book>
<bookId>2</bookId>
<bookName>老人与海1</bookName>
<bookAuthor>海明威2</bookAuthor>
<publish>机械工业出版社2016版</publish>
</book>
</books>
控制流程
public class BookService {
static OpreatData data; //操作xml文件的对象
Scanner in;
Book selected_book; // 当前选中的图书
public BookService() {
super();
init();
}
/**
* 启动
*/
public void start() {
controler();
}
/**
* 初始化
*/
public void init() {
data = new OpreatData();// 初始化操作
Book.id = data.getAllBook().size() + 1;// 得到有多少本书,计算下一本书的id
selected_book = null; // 当前选中的书籍设置为null
}
/**
* 流程控制
*/
public void controler() {
while (true) {
//主菜单
switch (mainMenu()) {
case 1://查询
getSelectBook();
show_book(selected_book);
break;
case 2://搜索
search_book();
break;
case 3://添加
add_book();
break;
case 4://修改
updata_book();
break;
case 5://删除
delete_book();
break;
case 0://退出
System.out.println("系统退出");
System.exit(0);
default:
System.out.println("操作代码错误,请重新输入!!!");
}
}
}
public int mainMenu() {
System.out.println("-------------------------------------");
System.out.println("|\t |");
System.out.println("|\t 图书管理系统 |");
System.out.println("|\t 1.查询图书 |");
System.out.println("|\t 2.搜索图书 |");
System.out.println("|\t 3.添加图书 |");
System.out.println("|\t 4.修改图书 |");
System.out.println("|\t 5.删除图书 |");
System.out.println("|\t 0.退出系统 |");
System.out.println("-------------------------------------");
System.out.println("请输入您要进行的操作代码:");
Scanner in = new Scanner(System.in);
return in.nextInt();
}
/**
* 列出所有图书供用户选择
*/
public void getSelectBook() {}
/**
* 搜索图书
*/
public void search_book() {}
/**
* 显示图书信息
*/
public void show_book(Book book) {}
/**
* 修改图书
*/
public void updata_book() {}
/**
* 添加图书
*/
public void add_book() {}
/**
* 删除图书
*/
public void delete_book() {}
}
以controller为中心,来控制流程
然后我们把各个方法补充完整
public class BookService {
static OpreatData data;
Scanner in;
Book selected_book; // 当前选中的图书
public BookService() {
super();
init();
}
/**
* 启动
*/
public void start() {
controler();
}
/**
* 初始化
*/
public void init() {
data = new OpreatData();// 初始化操作
Book.id = data.getAllBook().size() + 1;// 得到有多少本书,计算下一本书的id
selected_book = null; // 当前选中的书籍设置为null
}
/**
* 流程控制
*/
public void controler() {
//...
}
public int mainMenu() {
//...
}
/**
* 列出所有图书供用户选择
*/
public void getSelectBook() {
//得到一个book列表
List<Book> list = data.getAllBook();
Book book = null;
for (int i = 0; i < list.size(); i++) {
System.out.println((i + 1) + "." + list.get(i).toString());
}
System.out.println("请输入您要进行操作的书籍代码: 0.返回");
Scanner in = new Scanner(System.in);
int u = in.nextInt();
if (u > list.size()) {
System.out.println("没有这本书");
} else if (u == 0) {
return;
} else {
//选中这本书
selected_book = list.get(u - 1);
}
}
/**
* 搜索图书
*/
public void search_book() {
List<Book> bookList = null;
System.out.println("------------图书信息搜索:------------------");
while (true) {
in = new Scanner(System.in);
System.out.println("请输入您要进行的操作代码:1.搜索 2.放弃并返回主菜单");
int u = in.nextInt();
if (u == 1) {// 搜索
System.out.print("请输入要搜索的图书名称:");
String bookName = in.next();
bookList = data.search(bookName);
System.out.println("搜索结果");
if (bookList.size() == 0) {
System.out.println("没有这本书!");
}
for (int i = 0; i < bookList.size(); i++) {
System.out.println((i + 1) + ". " + bookList.get(i).toString());
}
} else if (u == 2) {
return;
} else {
System.out.println("输入操作代码有误,请重新输入!!!");
}
}
}
/**
* 显示图书信息
*/
public void show_book(Book book) {
selected_book = book; // 设置当前操作对象
System.out.println("------------图书信息:------------------");
System.out.println("图书名称:" + book.getBookName());
System.out.println("\n作者:" + book.getBookAuthor());
System.out.println("\n出版社:" + book.getPublish());
while (true) {
System.out.println("\n请输入您要进行的操作代码:1.修改 2.删除 0.返回主菜单");
in = new Scanner(System.in);
int u = in.nextInt();
if (u == 1) {
updata_book();
return;
} else if (u == 2) {
delete_book();
return;
} else if (u == 0) {
return; // 返回控制端
} else {
System.out.println("操作代码错误!!!");
}
}
}
/**
* 修改图书
*/
public void updata_book() {
System.out.println("------------修改图书:------------------");
in = new Scanner(System.in);
if(selected_book == null) {
System.out.println("当前没有选中的图书,请选中后操作");
//让用户去选择一本书
getSelectBook();
}
System.out.println("当前选中图书:" + selected_book.toString());
System.out.println("确认要修改吗? y:修改,r:重选,其他字符退出");
String confirm = in.next();
if("y".equals(confirm)) {
//继续
}else if("r".equals(confirm)) {
//选一本书后,继续
getSelectBook();
}else {
return;
}
System.out.println("图书名称:" + selected_book.getBookName());
System.out.println("新的图书名称:");
String bookName = in.next();
System.out.println("作者:" + selected_book.getBookAuthor());
System.out.println("\n新的作者:");
String bookAuthor = in.next();
System.out.println("出版社:" + selected_book.getPublish());
System.out.println("\n新的出版社:");
String publish = in.next();
while (true) {
System.out.println("\n请输入您要进行的操作代码:1.保存 2.放弃并返回主菜单");
int u = in.nextInt();
if (u == 1) {
Book book = new Book(selected_book.getBookId(), bookName, bookAuthor, publish);
data.updata_book(book);
System.out.println("修改成功");
System.out.println("1. " + book.toString());
break;
} else if (u == 2) {
break;// 什么都不操作
} else {
System.out.println("操作代码错误!!!");
}
}
}
/**
* 添加图书
*/
public void add_book() {
System.out.println("----------请填写图书信息:----------------");
in = new Scanner(System.in);
System.out.println("图书名称:");
String bookName = in.next();
System.out.println("\n作者:");
String bookAuthor = in.next();
System.out.println("\n出版社:");
String publish = in.next();
while (true) {
System.out.println("\n请输入您要进行的操作代码:1.保存 2.放弃并返回主菜单");
int u = in.nextInt();
if (u == 1) {
String bookId = Book.id + "";
Book book = new Book(bookId, bookName, bookAuthor, publish);
data.add_book(book);
System.out.println("添加成功");
System.out.println("1. " + book.toString());
return;
} else if (u == 2) {
return;// 什么都不操作
} else {
System.out.println("操作代码错误!!!");
}
}
}
/**
* 删除图书
*/
public void delete_book() {
System.out.println("------------删除图书:------------------");
if(selected_book == null) { //未选中的情况,列出图书,让选择
getSelectBook();
}
if (selected_book != null) {//图书被选中,可以直接删除
System.out.println("当前已经选中图书:" + selected_book.toString());
System.out.println("确认删除吗?(y/其他输入终止操作)");
String confirm = in.next();
if("y".equals(confirm)) {
data.delete_book(selected_book);
System.out.println("删除成功!");
}else {
System.out.println("终止删除!");
}
}else {
System.out.println("删除失败,或者是没有选中的图书");
}
}
}
去实现OpreatData中未完成的方法
- 常用的提取出来
public class DOMUtil {
final static String PATH = "src/resource/book/books.xml";
/**
* 获得根节点元素
*
* @param path
* @return
*/
public static Element getRoot() {
return getDocument().getRootElement();
}
/**
* 获取一个文档对象
*
* @param path
* @return Document
*/
public static Document getDocument() {
// 创建一个Reader(字符输入流)
SAXReader reader = new SAXReader();
Document document = null;
try {
document = reader.read(new File(PATH));
} catch (DocumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return document;
}
/**
* 写入xml文档
*
* @param document
* @param path
*
*/
public static void write(Document document) {
// 设置保存的格式化器 1. \t,使用什么来完成缩进 2. true, 是否要添加换行
OutputFormat format = new OutputFormat("\t", true);
format.setTrimText(true); //去掉空白
format.setEncoding("UTF-8");
XMLWriter writer = null;
try {
writer = new XMLWriter(new FileWriter(new File(PATH)),format);
writer.write(document);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
try {
writer.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
OpreatData.java
public class OpreatData {
/**
* 取得书籍列表
* @return
*/
public List<Book> getAllBook() {
List<Book> list = new ArrayList();
try {
// 获取Document当中的根节点元素
Element booksElement = DOMUtil.getRoot();
// 获取colleges元素的所有子节点元素
List<Element> childrenElements = booksElement.elements();
for (Element bookElement : childrenElements) {
String bookId = bookElement.element("bookId").getText();
String bookName = bookElement.element("bookName").getText();
String bookAuthor = bookElement.element("bookAuthor").getText();
String publish = bookElement.element("publish").getText();
Book book = new Book(bookId,bookName,bookAuthor,publish);
list.add(book);
}
} catch (Exception e) {
e.printStackTrace();
}
return list;
}
/**
* 通过名称搜寻
* @param bookName
* @return
*/
public List<Book> search(String bookName) {
List<Book> list = new ArrayList();
try {
// 获取Document
Document document = DOMUtil.getDocument();
// 使用xpath定位
List<Node> books = document.selectNodes("/books/book[bookName='" + bookName + "']");
if(books != null) {//如果不为空
for(int i = 0; i < books.size(); i++) {
Element bookElement = (Element) books.get(i);
String bookId = bookElement.element("bookId").getText();
String bookName_t = bookElement.element("bookName").getText();
String bookAuthor = bookElement.element("bookAuthor").getText();
String publish = bookElement.element("publish").getText();
Book book = new Book(bookId,bookName_t,bookAuthor,publish);
list.add(book);
}
}
} catch (Exception e) {
e.printStackTrace();
}
return list;
}
/**
* 添加一本书
* @param book
*/
public void add_book(Book book) {
//文档对象
Document document = DOMUtil.getDocument();
// 获取Document当中的根节点元素
Element booksElement = document.getRootElement();
Element newBook = booksElement.addElement("book");
newBook.addElement("bookId").setText(book.getBookId());
newBook.addElement("bookName").setText(book.getBookName());
newBook.addElement("bookAuthor").setText(book.getBookAuthor());
newBook.addElement("publish").setText(book.getPublish());
DOMUtil.write(document);
Book.id++;
}
public void delete_book(Book book) {
Document document = DOMUtil.getDocument();
Element deleteElement = (Element) document.selectSingleNode("/books/book[bookId='" + book.getBookId() + "']");
//取得父亲节点
Element parentElement = deleteElement.getParent();
parentElement.remove(deleteElement);
DOMUtil.write(document);
Book.id--;
}
public void updata_book(Book book) {
Document document = DOMUtil.getDocument();
/**
* 使用xpath定位要修改的元素
*/
Element updataElement = (Element) document.selectSingleNode("/books/book[bookId='" + book.getBookId() + "']");
// 修改元素当中的文本的值为新的文本
updataElement.element("bookName").setText(book.getBookName());
updataElement.element("bookAuthor").setText(book.getBookAuthor());
updataElement.element("publish").setText(book.getPublish());
DOMUtil.write(document);
}
}
完成
测试
public class Main {
public static void main(String[] args) {
BookService bookService = new BookService();
bookService.start();
}
}
坑
- 文件编码问题,eclipse默认是GBK,默认是utf-8,会报错,用记事本打开-》另存为(选择编码为utf-8)保存即可。