xml 小练习

以XML为一个小的数据库,写一个小练习,命令式菜单,练习java解析xml--dom方式的增删改查。

下面是项目分包:注意xml文件跟src是并列的。

一开始Contact.xml文档如下图:

写一个工具类生产uuid:

package cn.hncu.contact.util;

import java.util.UUID;

public class IDGenerator {
	 private IDGenerator(){
		 
	 }
	 
     public static String  getId(){
    	 String uuid=UUID.randomUUID().toString();
    	  uuid=uuid.replaceAll("-", "");
    	 return uuid;
     }
}

重点:因为是多用户,虽然是单机版,但这里要用到单例!!!

生成单例的代码如下,写一个工厂类:

package cn.hncu.contact.common;

import java.io.File;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.TransformerFactoryConfigurationError;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.Document;


public class DocumentFactory {
    private static Document dom;
    private static File file;
    static{
    	try {
			file = new File("./xml/Contact.xml");
			if(!file.exists()){
				throw new Exception("数据库不存在!");
			}
			DocumentBuilder db=DocumentBuilderFactory.newInstance().newDocumentBuilder();
			dom = db.parse(file);
		} catch (ParserConfigurationException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}
    }
    
    public static Document getDocument(){
    	return dom;
    }
    
    public static void save(){
    	try {
			Transformer trans=TransformerFactory.newInstance().newTransformer();
			trans.transform(new DOMSource(dom), new StreamResult(file));
		} catch (TransformerConfigurationException e) {
			e.printStackTrace();
		} catch (TransformerFactoryConfigurationError e) {
			e.printStackTrace();
		} catch (TransformerException e) {
			e.printStackTrace();
		}
    	
    }
}

然后写一个测试类 :测试一下工具类:

package cn.hncu.testContact;

import org.junit.Test;
import org.w3c.dom.Document;

import cn.hncu.contact.common.DocumentFactory;
import cn.hncu.contact.util.IDGenerator;

public class ContactTest {
	@Test
	   public void testGetId(){
		  String id = IDGenerator.getId();
		  System.out.println(id);
		  System.out.println(IDGenerator.getId());
		  System.out.println(IDGenerator.getId());
	   }
	   
	   
	   @Test
	   public void testGetDom(){
		   Document dom1 = DocumentFactory.getDocument();
		   Document dom2 = DocumentFactory.getDocument();
		   System.out.println(dom1.hashCode());
		   System.out.println(dom2.hashCode());
	   }
}

结果如下: 

第一个是生成的单例的hashCode,一样说明,是单例! 第二个是随机生成的UUID

接下来写Dao层,接口,工厂,实现类:

package cn.hncu.contact.dao;

import java.util.List;
import java.util.Map;

public interface ContactDAO {
   public boolean login(String name,String pwd);
   public void reg(String name,String pwd);
   public boolean add(String name, String tel, String sex);
   public List<Map<String, String>> queryAllContacts();
   public String del(String id);
   public boolean upd(String id,String name,String tel,String sex,String target);
}
package cn.hncu.contact.dao.factory;

import cn.hncu.contact.dao.ContactDAO;
import cn.hncu.contact.dao.impl.ContactDaoImpl;

public class ContactDAOFactory {
   private ContactDAOFactory(){
	   
   }
   public static ContactDAO getContactDao(){
	   return new ContactDaoImpl();
   }
}
package cn.hncu.contact.dao.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

import cn.hncu.contact.common.DocumentFactory;
import cn.hncu.contact.dao.ContactDAO;
import cn.hncu.contact.util.IDGenerator;

public class ContactDaoImpl implements ContactDAO {

	private Element eCurrentUser = null; // 当前用户

	@Override
	public boolean login(String name, String pwd) {
		Document dom = DocumentFactory.getDocument();
		Element root = (Element) dom.getFirstChild();
		NodeList eUserList = root.getElementsByTagName("user");
		for (int i = 0; i < eUserList.getLength(); i++) {
			Element eUser = (Element) eUserList.item(i);
			if (eUser.getAttribute("name").equalsIgnoreCase(name)
					&& eUser.getAttribute("pwd").equals(pwd)) {
				eCurrentUser = eUser; // 把当前登录成功的用户保存到类成员变量eCurrentUser,供其它业务方法使用
				return true;
			}
		}

		return false;
	}

	@Override
	public void reg(String name, String pwd) {
		Document dom = DocumentFactory.getDocument();
		// 把新用户节点添加到dom中
		Element root = (Element) dom.getFirstChild();

		// 创建一个新的用户节点 eNewUser
		Element eNewUser = dom.createElement("user");
		eNewUser.setAttribute("name", name);
		eNewUser.setAttribute("pwd", pwd);
		// 把eNewUser添加为root的孩子
		root.appendChild(eNewUser);

		// 保存
		DocumentFactory.save();
	}

	@Override
	public boolean add(String name, String tel, String sex) {
		Document dom = DocumentFactory.getDocument();
		// 创建一个新的联系人节点<contact>, eNewContact对象
		Element eNewContact = dom.createElement("contact");
		eNewContact.setAttribute("id", IDGenerator.getId());

		// 创建一个<name>元素对应的 eName,并把它添加成eNewContact的孩子
		Element eName = dom.createElement("name");
		eName.setTextContent(name);
		eNewContact.appendChild(eName);

		// 创建一个<tel>元素对应的 eTel,并把它添加成eNewContact的孩子
		Element eTel = dom.createElement("tel");
		eTel.setTextContent(tel);
		eNewContact.appendChild(eTel);

		// 创建一个<sex>元素对应的 eSex,并把它添加成eNewContact的孩子
		Element eSex = dom.createElement("sex");
		eSex.setTextContent(sex);
		eNewContact.appendChild(eSex);

		// 把上面组装好的eNewContact添加成eCurrentUser的孩子
		eCurrentUser.appendChild(eNewContact);

		// 序列化
		DocumentFactory.save();
		return false;
	}

	@Override
	public List<Map<String, String>> queryAllContacts() {
		List<Map<String, String>> resultList = new ArrayList<Map<String, String>>();
		if (eCurrentUser == null) {
			return resultList;
		}
		NodeList eContactList = eCurrentUser.getElementsByTagName("contact");
		for (int i = 0; i < eContactList.getLength(); i++) {
			Element eContact = (Element) eContactList.item(i);
			// 把每一个eContact中的信息封装成一个map
			Map<String, String> map = new HashMap<String, String>();
			map.put("id", eContact.getAttribute("id"));// id
			map.put("name", eContact.getElementsByTagName("name").item(0)
					.getTextContent());// name
			map.put("sex", eContact.getElementsByTagName("sex").item(0)
					.getTextContent());// sex
			map.put("tel", eContact.getElementsByTagName("tel").item(0)
					.getTextContent());// tel

			// 把map添加到resultList中
			resultList.add(map);
		}
		return resultList;
	}

	@Override
	public String del(String id) {
		NodeList eContactList = eCurrentUser.getElementsByTagName("contact");
		for (int i = 0; i < eContactList.getLength(); i++) {
			Element eContact = (Element) eContactList.item(i);
			String iid = eContact.getAttribute("id");
			if (id.equals(iid)) {
				// 先保存要返回的数据
				String name = eContact.getElementsByTagName("name").item(0)
						.getTextContent();
				eContact.getParentNode().removeChild(eContact);
				DocumentFactory.save();

				return name;
			}
		}
		return null;

	}

	@Override
	public boolean upd(String id, String name, String tel, String sex,String target) {
		NodeList eContactList = eCurrentUser.getElementsByTagName("contact");
		boolean boo = false;
		for (int i = 0; i < eContactList.getLength(); i++) {
			Element eContact = (Element) eContactList.item(i);
			String iid = eContact.getAttribute("id");
			if (id.equals(iid)) {
				if ("0".equals(target)) {
					tel = eContact.getElementsByTagName("tel").item(0)
							.getTextContent();
					sex = eContact.getElementsByTagName("sex").item(0)
							.getTextContent();
					Element eName = (Element) eContact.getElementsByTagName(
							"name").item(0);
					eName.setTextContent(name);
					boo = true;
				} else if ("1".equals(target)) {
					sex = eContact.getElementsByTagName("sex").item(0)
							.getTextContent();
					name = eContact.getElementsByTagName("name").item(0)
							.getTextContent();
					Element eTel = (Element) eContact.getElementsByTagName(
							"tel").item(0);
					eTel.setTextContent(tel);
					boo = true;
				} else if ("2".equals(target)) {
					tel = eContact.getElementsByTagName("tel").item(0)
							.getTextContent();
					name = eContact.getElementsByTagName("name").item(0)
							.getTextContent();
					Element eSex = (Element) eContact.getElementsByTagName(
							"sex").item(0);
					eSex.setTextContent(sex);
					boo = true;
				} else {
					boo = false;
				}
			
			}	
			DocumentFactory.save();
	    }
		return boo;
	}
   
}

最后是表现层:

package cn.hncu.contact.cmd;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;

import cn.hncu.contact.dao.ContactDAO;
import cn.hncu.contact.dao.factory.ContactDAOFactory;

public class ContactAction {
	private Scanner sc = null;
	// 声明一个联系人id集合---存放序号与id对应关系的hashMap
	// 在每次显示所有联系人时重新存入,在删除与修改时读取
	Map<Integer, String> idMap = null;
	// 注入dao
	private ContactDAO dao = ContactDAOFactory.getContactDao();

	public ContactAction() {
		sc = new Scanner(System.in);
		System.out.println("※※警告用户:非GBK编码时,MyEclipse控制台中不支持中文输入!※※");
		System.out
				.println("---------------------------------------------------");

		while (true) {
			// 软件的主界面显示
			System.out.println("1:登录");
			System.out.println("2:注册");
			System.out.println("0:退出");

			String op = sc.nextLine();
			if ("1".equals(op)) {
				login();
			} else if ("2".equals(op)) {
				reg();
			} else if ("0".equals(op)) {
				System.out.println("程序马上退出....");
				break;
			}

		}
	}

	private void reg() {
		System.out.println("*********************");
		System.out.println("*      用户注册               *");
		System.out.println("*********************");
		System.out.println("请输入用户名:");
		String name = sc.nextLine();
		System.out.println("请输入密码:");
		String pwd = sc.nextLine();
		System.out.println("请再次输入密码:");
		String pwd2 = sc.nextLine();
		if (name.trim().length() > 0) {
			if (pwd.equals(pwd2)) {
				// 调用dao层进行注册
				dao.reg(name, pwd);
				System.out.println("恭喜,注册成功!");
			} else {
				System.out.println("两次密码不一致,请重新注册!");
				reg();
			}
		} else {
			System.out.println("姓名不能为空字符");
			reg();
		}

	}

	private void login() {
		System.out.println("*********************");
		System.out.println("*      用户登录               *");
		System.out.println("*********************");
		System.out.println("请输入用户名:");
		String name = sc.nextLine();
		System.out.println("请输入密码:");
		String pwd = sc.nextLine();
		boolean boo = dao.login(name, pwd);
		if (boo) {
			System.out.println("恭喜,登录成功,请选择下一步操作!");
			operation();
		} else {
			System.out.println("登录失败!!!!");
		}
	}

	private void operation() {
		System.out.println("1:显示所有联系人");
		System.out.println("2:添加联系人");
		System.out.println("3:删除联系人");
		System.out.println("4:修改联系人");
		System.out.println("0:返回到软件主界面");

		String sel = sc.nextLine();
		if ("1".equals(sel)) {// 显示所有联系人
			queryAll();
		} else if ("2".equals(sel)) {// 添加联系人
			addContact();
		} else if ("3".equals(sel)) {// 删除联系人
			delContact();
		} else if ("4".equals(sel)) {// 修改联系人
           updContact();
		} else if ("0".equals(sel)) {// 退回到上一级菜单
			return;
		}
		operation();
	}

	private void queryAll() {
		List<Map<String, String>> list = dao.queryAllContacts();
		System.out.println("序号\t姓名\t电话\t性别");
		System.out.println("-------------------------------");
		idMap = new HashMap<Integer, String>();
		int i = 1;
		for (Map<String, String> map : list) {
			String id = map.get("id");
			idMap.put(i, id); // 为以后的删除与修改做存储

			String name = map.get("name");
			String tel = map.get("tel");
			String sex = map.get("sex");
			if ("0".equals(sex)) {
				sex = "男";
			} else {
				sex = "女";
			}
			System.out.println((i++) + "\t" + name + "\t" + tel + "\t"
					+ sex);
		}
		
	}

	private void updContact() {
		queryAll();
		String name=null;
		String sex=null;
		String tel=null;
		boolean boo=false;
		System.out.println("请输入要修改联系人的序号");
		int num = sc.nextInt();
		sc.nextLine();//吸掉多余的换行符
		String id = idMap.get(num);
		System.out.println("请输入要修改的属性:0-姓名 1-电话 2-性别");
		String target=sc.nextLine();
		if ("0".equals(target)) {
			System.out.println("请输入要修改姓名的内容:");
			name=sc.nextLine();
		    boo=dao.upd(id, name, tel, sex,target);
		}else if("1".equals(target)){
			System.out.println("请输入要修改电话的内容:");
			tel=sc.nextLine();
		    boo=dao.upd(id, name, tel, sex,target);
		}else if("2".equals(target)){
			System.out.println("请输入要修改性别的内容:");
			sex=sc.nextLine();
		    boo=dao.upd(id, name, tel, sex,target);
		}
		if(boo){
			System.out.println("修改成功~~");
			queryAll();
		}else{
			System.out.println("修改失败!!");
		}
	}

	private void delContact() {
		queryAll();
		System.out.println("请输入要删除联系人的序号");
		int num = sc.nextInt();
		sc.nextLine();//吸掉多余的换行符
		String id = idMap.get(num);
		String name = dao.del(id);
		if(name!=null){
			System.out.println("已经删除联系人:"+name);
			queryAll();
		}else{
			System.out.println("不存在该联系人");
		}
	}

	private void addContact() {
		System.out.println("请输入联系人的信息");
		System.out.println("姓名:");
		String name = sc.nextLine();
		System.out.println("电话:");
		String tel = sc.nextLine();
		System.out.println("性别:");
		String sex = sc.nextLine();
		
		dao.add(name,tel,sex);
	}

	public static void main(String[] args) {
		new ContactAction();
	}

}

最后的XML文件是:

<?xml version="1.0" encoding="UTF-8" standalone="no"?><contacts>
	<user name="1234" pwd="1234">
		<contact id="2eaa2dbb32064cf0afd6a5e1013a6cbf">
			<name>simons</name>
			<tel>88888</tel>
			<sex>0</sex>
		</contact>
		<contact id="7fe2cf73804645f0abbca1303b78ec9a">
			<name>james</name>
			<tel>99999</tel>
			<sex>0</sex>
		</contact>
	<contact id="f49e5457dc144ca483fbbf82667cf7d3"><name>111</name><tel>56666</tel><sex>0</sex></contact></user>
	<user name="tom" pwd="1111">
		<contact id="688f0e262e5841ba8d6ceceffa9f9f4d">
			<name>lx</name>
			<tel>12333</tel>
			<sex>1</sex>
		</contact>
	</user>
</contacts>

 

原文链接:加载失败,请重新获取