dom4j小demo

本文通过一个简单的图书管理程序介绍了如何使用dom4j操作XML文件,包括图书的查询、修改、删除和添加功能。在实践中遇到的文件编码问题需要注意,Eclipse默认编码为GBK,需要将XML文件另存为UTF-8避免错误。
摘要由CSDN通过智能技术生成

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)保存即可。
01-04
package xmllab;<br><br>import java.io.File;<br>import java.io.FileWriter;<br>import java.util.Iterator;<br>import java.util.List;<br>import org.dom4j.Attribute;<br>import org.dom4j.Document;<br>import org.dom4j.DocumentHelper;<br>import org.dom4j.Element;<br>import org.dom4j.io.OutputFormat;<br>import org.dom4j.io.SAXReader;<br>import org.dom4j.io.XMLWriter;<br><br>/**<br><br>* @author Holen Chen<br><br>*/<br><br>public class Dom4jDemo {<br> public Dom4jDemo() {<br> }<br><br> /**<br><br> * 建立一个XML文档,文档名由输入属性决定<br><br> * @param filename 需建立的文件名<br><br> * @return 返回操作结果, 0表失败, 1表成功<br><br> */<br><br> public int createXMLFile(String filename){<br> /** 返回操作结果, 0表失败, 1表成功 */<br> int returnValue = 0;<br> /** 建立document对象 */<br> Document document = DocumentHelper.createDocument();//<?xml version="1.0" encoding="UTF-8"?><br> /** 建立XML文档的根books */<br> Element booksElement = document.addElement("books");//<books></books><br> /** 加入一行注释 */<br> booksElement.addComment("This is a test for dom4j, holen, 2004.9.11");//<books><!--This is a test for dom4j, holen, 2004.9.11--></books><br> /** 加入第一个book节点 */<br> Element bookElement = booksElement.addElement("book");//<books><!--This is a test for dom4j, holen, 2004.9.11--><book></book></books><br> /** 加入show属性内容 */<br> bookElement.addAttribute("show","yes");//<books><!--This is a test for dom4j, holen, 2004.9.11--><book show="yes"></book></books><br> /** 加入title节点 */<br> Element titleElement = bookElement.addElement("title");//<books><!--This is a test for dom4j, holen, 2004.9.11--><book show="yes"><title></title></book></books><br> /** 为title设置内容 */<br> titleElement.setText("Dom4j Tutorials");//<books><!--This is a test for dom4j, holen, 2004.9.11--><book show="yes"><title>Dom4j Tutorials</title></book></books><br> /** 类似的完成后两个book */<br> bookElement = booksElement.addElement("book");<br> bookElement.addAttribute("show","yes");<br> titleElement = bookElement.addElement("title");<br> titleElement.setText("Lucene Studing");<br> bookElement = booksElement.addElement("book");<br> bookElement.addAttribute("show","no");<br> titleElement = bookElement.addElement("title");<br> titleElement.setText("测试");<br> /** 加入owner节点 */<br> Element ownerElement = booksElement.addElement("owner");<br> ownerElement.setText("O'Reilly");<br> try{<br> /** 将document中的内容写入文件中 */<br> XMLWriter writer = new XMLWriter(new FileWriter(new File(filename)));<br> writer.write(document);<br> writer.close();<br> /** 执行成功,需返回1 */<br> returnValue = 1;<br> }catch(Exception ex){<br> ex.printStackTrace();<br> }<br> return returnValue;<br> }<br><br> /**<br> * 修改XML文件中内容,并另存为一个新文件<br> * 重点掌握dom4j中如何添加节点,修改节点,删除节点<br> * @param filename 修改对象文件<br> * @param newfilename 修改后另存为该文件<br> * @return 返回操作结果, 0表失败, 1表成功<br> */<br><br> public int ModiXMLFile(String filename,String newfilename){<br> int returnValue = 0;<br> try{<br> SAXReader saxReader = new SAXReader();<br> Document document = saxReader.read(new File(filename));<br> /** 修改内容之一: 如果book节点中show属性的内容为yes,则修改成no */<br> /** 先用xpath查找对象 */<br> List list = document.selectNodes("/books/book/@show" );<br> Iterator iter = list.iterator();<br> while(iter.hasNext()){<br> Attribute attribute = (Attribute)iter.next();<br> if(attribute.getValue().equals("yes")){<br> attribute.setValue("no");<br> }<br> }<br> /**<br> * 修改内容之二: 把owner项内容改为Tshinghua<br> * 并在owner节点中加入date节点,date节点的内容为2004-09-11,还为date节点添加一个属性type<br> */<br> list = document.selectNodes("/books/owner" );<br> iter = list.iterator();<br> if(iter.hasNext()){<br> Element ownerElement = (Element)iter.next();<br> ownerElement.setText("Tshinghua");<br> Element dateElement = ownerElement.addElement("date");<br> dateElement.setText("2007-09-06");<br> dateElement.addAttribute("type","Gregorian calendar");<br> }<br><br> /** 修改内容之三: 若title内容为Dom4j Tutorials,则删除该节点 */<br><br> list = document.selectNodes("/books/book");<br><br> iter = list.iterator();<br><br> while(iter.hasNext()){<br><br> Element bookElement = (Element)iter.next();<br><br> Iterator iterator = bookElement.elementIterator("title");<br><br> while(iterator.hasNext()){<br><br> Element titleElement=(Element)iterator.next();<br><br> if(titleElement.getText().equals("Dom4j Tutorials")){<br><br> bookElement.remove(titleElement);<br><br> }<br><br> }<br><br> }<br><br><br><br> try{<br><br> /** 将document中的内容写入文件中 */<br><br> XMLWriter writer = new XMLWriter(new FileWriter(new File(newfilename)));<br><br> writer.write(document);<br><br> writer.close();<br><br> /** 执行成功,需返回1 */<br><br> returnValue = 1;<br><br> }catch(Exception ex){<br><br> ex.printStackTrace();<br><br> }<br><br><br><br> }catch(Exception ex){<br><br> ex.printStackTrace();<br><br> }<br><br> return returnValue;<br><br> }<br><br><br> /**<br><br> * 格式化XML文档,并解决中文问题<br><br> * @param filename<br><br> * @return<br><br> */<br><br> public int formatXMLFile(String filename){<br><br> int returnValue = 0;<br><br> try{<br><br> SAXReader saxReader = new SAXReader();<br><br> Document document = saxReader.read(new File(filename));<br><br> XMLWriter writer = null;<br><br> /** 格式化输出 */<br><br> OutputFormat format = OutputFormat.createPrettyPrint();<br><br> /** 指定XML编码 */<br><br> format.setEncoding("GBK");<br><br> writer= new XMLWriter(new FileWriter(new File(filename)),format);<br><br> writer.write(document);<br><br> writer.close();<br><br> /** 执行成功,需返回1 */<br><br> returnValue = 1;<br><br> }catch(Exception ex){<br><br> ex.printStackTrace();<br><br> }<br><br> return returnValue;<br><br> }<br><br><br><br> public static void main(String[] args) {<br><br> Dom4jDemo temp = new Dom4jDemo();<br><br> //System.out.println(temp.createXMLFile("d://testxml.xml"));<br> <br> //System.out.println(temp.ModiXMLFile("d://testxml.xml","d://testxml2.xml"));<br>// try{<br> System.out.println(temp.formatXMLFile("d://testxml2.xml"));<br>// // System.out.println(temp.formatXMLFile("E:\\test.xml"));<br>// }<br>// catch(Exception e)<br>// {<br>// // e.printStackTrace();<br>// System.out.print("error!");<br>//<br>// }<br><br> }<br>}<br>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值