首先我们要知道,如何通过java来对xml进行操作
JDK中有两个专用于进行dom编程的包:
1) org.w3c.dom —-w3c是制定标准
2) javax.xml.parsers —-sun公司开发出来给我们解析用的
入口: Document接口(来自w3c,org.w3c.dom包) –> 要用工厂方法获得该dom对象 —工厂方法来自sun公司(javax.xml.parsers包)
1.获取dom对象
public class DomDemo {
@Test
public void getDom() throws Exception{
//获取dom对象
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document dom = db.parse("./xml/users.xml");
System.out.println(dom);
}
}
要遍历文档,最好的选择方式是:
采用Element中的getElementsByTagName(String name),
返回类型为:NodeList, 获取当前元素下面的所有对应标签的那些子元素(
仅仅是标签节点—能够去除文本内容尤其是空白符的干扰)。
建议不要采用如下两种方式:
1)通过Node中的 getChildNodes(),返回类型为:NodeList, 获取当前节点的所有 子节点(包括文本内容和标签节点)—-不选择的理由:文本内容尤其是空白符也是其中的孩子节点,会产生干扰
2)通过Document的getElementById(String elementId), 返回Element节点,
这种方式在browse-dom中用起来是非常方便的,但在Java-dom中必须得给
DocumentBuilderFactory对象设置schema
读取第一个节点中的值
public void getName2() throws Exception{
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document dom = db.parse(new File("./xml/users.xml"));
Node root = dom.getFirstChild();
System.out.println("NodeName:"+root.getNodeName());
System.out.println("---------------------");
//采用建议的方式---Element中的getElementsByTagName(String name)
//为了使用Element中的方法,必须得强转成Element类型
Element eRoot = (Element)root;
NodeList userList= eRoot.getElementsByTagName("user");
Element eUser1 = (Element) userList.item(0);
NodeList nameList = eUser1.getElementsByTagName("name");
Node nameNode = nameList.item(0);
String name = nameNode.getTextContent();
System.out.println(name);
}
向xml中写入内容
//改 ---需求:把最后一个user的年龄改为 age+10
@Test
public void changeAge (){
try {
// 拿到 dom
/* DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document dom = db.parse(new File("./xml/users.xml"));*/
Document dom = getDom();
// 拿到最后一个user的age,并且年龄加10
Element root = (Element) dom.getFirstChild();
NodeList usersList = root.getElementsByTagName("user");
Element lastuser = (Element) usersList.item(usersList.getLength()-1);
Element age = (Element) lastuser.getElementsByTagName("age").item(0);
age.setTextContent( Integer.parseInt(age.getTextContent())+10+"");
//保存,把内存中操作的结果保存到 文档(硬盘)中
TransformerFactory tfF = TransformerFactory.newInstance();
Transformer tf = tfF.newTransformer();
tf.transform(new DOMSource(dom), new StreamResult("./xml/users.xml"));
} catch (Exception e) {
e.printStackTrace();
}
}
现在我们来制作用户通讯录管理的项目:
项目框架:
common工具类:
由于对xml文档进行存储和读取的代码冗余,所以将其作为一个工具类代码DocumentDaoFactory.java:
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.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;
public class DocumentDaoFactory {
private static Document dom;
private static File file;
private DocumentDaoFactory() {
}
static {
try {
file = new File("./xml/contact.xml");
if (!file.exists()) {
throw new RuntimeException("xml数据库不存在");
} else {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
dom=db.parse(file);
}
} catch (Exception e) {
throw new RuntimeException("xml数据库解析出错:"+e.getMessage(), e);
}
}
public static Document getDom(){
return dom;
}
public static void save(){
try {
TransformerFactory tf = TransformerFactory.newInstance();
Transformer trans = tf.newTransformer();
trans.transform( new DOMSource(dom), new StreamResult(file)); //
} catch (Exception e) {
throw new RuntimeException("xml数据库保存出错:"+e.getMessage(), e);
}
}
}
面向用户界面Contaction.java:
package cn.hncu.contact.cmd;
import java.util.Scanner;
import cn.hncu.contact.dao.ContactDao;
import cn.hncu.contact.dao.ContactDaoFactory.ContactDaoFactory;
public class Contaction {
private ContactDao dao=ContactDaoFactory.getContactDao();
private Scanner sc = null;
public Contaction() {
sc = new Scanner(System.in);
System.out.println("※※警告用户:MyEclipse控制台中不支持中文!※※");
while (true) {
System.out.println("1:登录");
System.out.println("2:注册");
System.out.println("3:退出");
String op = sc.nextLine();
if ("1".equals(op)) {
login();
} else if ("2".equals(op)) {
reg();
} else if ("3".equals(op)) {
System.out.println("您已经安全退出系统!");
break;
}
}
}
private void reg() {
System.out.println("请输入姓名:");
String name=sc.nextLine().trim();
System.out.println("请输入密码");
String pwd=sc.nextLine();
System.out.println("请确认密码");
String pwd2=sc.nextLine();
if(pwd.equals(pwd2)){
boolean boo=dao.reg(name,pwd);
if(boo){
System.out.println("恭喜你,注册成功");
}else{
System.out.println("注册失败");
reg();
}
}else{
System.out.println("两次密码不一致");
reg();
}
}
private void login() {
System.out.println("请输入姓名");
String name=sc.nextLine().trim();
System.out.println("请输入密码");
String pwd=sc.nextLine();
System.out.println("请确认密码");
String pwd2=sc.nextLine();
if(pwd.equals(pwd2)){
boolean boo=dao.login(name, pwd);
if(boo){
System.out.println("登陆成功");
doOpertate();
}else{
System.out.println("登录失败");
reg();
}
}else{
System.out.println("两次密码不一致");
reg();
}
}
private void doOpertate() {
System.out.println("1:显示所有联系人");
System.out.println("2:添加联系人");
System.out.println("3:删除联系人");
System.out.println("4:修改联系人");
System.out.println("0:退出");
String sel = sc.nextLine().trim();
if("1".equals(sel)){
//TODO:
}else if("2".equals(sel)){
//TODO:
}
}
public static void main(String[] args) {
new Contaction();
}
}
项目功能实现类:ContactDaoimpl.java
package cn.hncu.contact.dao.impl;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import cn.hncu.contact.common.DocumentDaoFactory;
import cn.hncu.contact.dao.ContactDao;
public class ContactDaoimpl implements ContactDao{
@Override
public boolean reg(String name, String pwd) {
Document dom=DocumentDaoFactory.getDom();
Element root=(Element) dom.getFirstChild();
NodeList list=root.getElementsByTagName("user");
for(int i=0;i<list.getLength();i++){
String nm=((Element)list.item(i)).getAttribute("name");
if(nm.trim().equalsIgnoreCase(name)){
return false;
}
}
Element eNewUser=dom.createElement("user");
eNewUser.setAttribute("name", name);
eNewUser.setAttribute("pwd", pwd);
root.appendChild(eNewUser);
DocumentDaoFactory.save();
return true;
}
@Override
public boolean login(String name, String pwd) {
Document dom=DocumentDaoFactory.getDom();
Element root=(Element) dom.getFirstChild();
NodeList list=root.getElementsByTagName("user");
for(int i=0;i<list.getLength();i++){
String nm=((Element)list.item(i)).getAttribute("name");
String pwd1=((Element)list.item(i)).getAttribute("pwd");
if(nm.equalsIgnoreCase(name)&&pwd1.equals(pwd)){
return true;
}
}
return false;
}
}
功能运行图:
此时xml文档也已经成功写入数据: