用java解析xml 有几种方式,官方的是sun公司的DOM、SAX,不过现在我们常用的是第三方包即dom4j。
今天讲的是DOM方式
首先,我们先写一个简单的xml文件。
接下来看DOM方式怎么解析XML
package cn.hncu.dom;
import java.io.File;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.junit.Test;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
public class DomParse {
@Test
public void Domo() throws Exception {
// 通过工厂调用静态方法创建DocumentBuilder对象
DocumentBuilder db = DocumentBuilderFactory.newInstance()
.newDocumentBuilder();
// 通过parse方法解析xml文件获得Document对象
Document dom = db.parse("./xml/users.xml");
// 利用Document对象进行DOM操作。
// xml的根节点是document对象的第一个子节点。
Node root = dom.getFirstChild();
String nm = root.getNodeName();// users根节点
System.out.println(nm);
System.out.println("---------------------");
// /通过Node获取子节点集合的方式,不建议使用,因为存在#text即空白符节点//
NodeList list = root.getChildNodes();// 返回<users>节点中的所有子节点
System.out.println(list.item(0).getNodeName());// #text---空白符
System.out.println(list.item(1).getNodeName());
System.out.println(list.item(2).getNodeName());
System.out.println("---------------------");
// /※※※建议通过Element获取子节点,可避开空白符的干扰,
/* 因为Element接口中有getElementsByTagName(String name)方法可以调用,而Node中没有*/
Element eUsers=(Element) root;
NodeList nodeList = eUsers.getElementsByTagName("user");//获取<users>中的所有<user>子节点---不包括空白节点
System.out.println(nodeList.item(0).getNodeName());
System.out.println(nodeList.item(1).getNodeName());
//nodeList2中的最后一个元素
System.out.println(nodeList.item( nodeList.getLength()-1).getNodeName());
//需求:把users.xml中的第一个user元素中的name值输出来
Element eUser=(Element) nodeList.item(0);
Node eName=(Node) eUser.getElementsByTagName("name").item(0);
System.out.println(eName.getTextContent());//标签没有value,只能获取内容
}
//需求: 把users.xml中的最后一个user元素中的age值输出来
@Test
public void getAgeOfLastUser() throws Exception{
Document dom=DocumentBuilderFactory.newInstance().newDocumentBuilder().parse("./xml/users.xml");
Node root=dom.getFirstChild();
Element eUsers = (Element) root;
NodeList nodelist = eUsers.getElementsByTagName("user");
Element eLastUser=(Element) nodelist.item(nodelist.getLength()-1);
String age = eLastUser.getElementsByTagName("age").item(0).getTextContent();
System.out.println("age:"+age);
}
//反模式: java-dom中最好不用getElementById()的方式来获取节点,因为该方式需要使用Schema,非常麻烦!有兴趣可以参看
@Test
public void getElementByIdDemo() throws Exception{
DocumentBuilder db = DocumentBuilderFactory.newInstance().newDocumentBuilder();
Document dom = db.parse( new File("./xml/users.xml") );
Element eNode = dom.getElementById("A002");
System.out.println(eNode); //null
}
}
其次是DOM方式的CRUD
package cn.hncu.dom;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.junit.Test;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
public class DomCDUQ {
/*
* DOM解析方式:增删改查
*/
// 查: 把users.xml中的每一个user元素的信息输出
@Test
public void iteratorDemo() throws Exception {
// document
Document dom = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse("./xml/users.xml");
// root
Element eUsers = (Element) dom.getFirstChild();
NodeList nodeList = eUsers.getElementsByTagName("user");
// 遍历
for (int i = 0; i < nodeList.getLength(); i++) {
Element eUser = (Element) nodeList.item(i);
String name = eUser.getElementsByTagName("name").item(0).getTextContent();
String age = eUser.getElementsByTagName("age").item(0).getTextContent();
String id = eUser.getAttribute("id");
System.out.println("id:" + id + ",name:" + name + ",age:" + age);
System.out.println("----------");
}
}
// 改: 把users.xml中的最后一个user元素的age设为20
// 基本套路:根据要求把内存中的dom对象进行修改,然后利用Transform工具进行序列化
@Test
public void updateDemo() throws Exception {
// document
Document dom = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse("./xml/users.xml");
// root
Element eUsers = (Element) dom.getFirstChild();
NodeList nodeList = eUsers.getElementsByTagName("user");
// 获取最后一个<user>节点
Element eLastUser = (Element) nodeList.item(nodeList.getLength() - 1);
Node eAge = eLastUser.getElementsByTagName("age").item(0);
eAge.setTextContent("120");
//前面部分只是更改了内存中dom树的信息,要永久生效必须序列化且修改时还要覆盖原文件///
/*把dom对象序列化到磁盘文件 ----※技术入口:
*要用到javax.xml.transform.Transformer类中的
*transform(source,result)方法*/
Transformer trans=TransformerFactory.newInstance().newTransformer();
trans.transform(new DOMSource(dom), new StreamResult("./xml/users.xml"));
//若文件已经存在则是修改,否则是"另存为"
}
// 增: 向users.xml中的添加一个user元素
// 基本套路:根据要求把内存中的dom对象进行修改,然后利用Transform工具进行序列化
@Test
public void addDemo() throws Exception {
// document
Document dom = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse("./xml/users.xml");
Element eUsers = (Element) dom.getFirstChild();
//创建一个新的<user>元素,并组装成一棵子树添加到<users>节点
Element eUser = dom.createElement("user");//复杂节点需要添加子节点
eUser.setAttribute("id", "B001");;//属性可以直接设置
//简单节点直接设置内容文本与属性
Element eName = dom.createElement("name");
eName.setTextContent("张三");
Element eAge = dom.createElement("age");
eAge.setTextContent("28");
//组装<user>子树: 让eUser添加两个孩子:eName,eAge
eUser.appendChild(eName);
eUser.appendChild(eAge);
//把子树eUser添加到dom树的文档根节点eUsers
eUsers.appendChild(eUser);
///不要忘记序列化//
Transformer trans=TransformerFactory.newInstance().newTransformer();
trans.transform(new DOMSource(dom), new StreamResult("./xml/users.xml"));
}
//删: 把users.xml中的最后一个user元素删除
// 基本套路:根据要求把内存中的dom对象进行修改,然后利用Transform工具进行序列化
@Test
public void delDemo() throws Exception {
// document
Document dom = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse("./xml/users.xml");
Element eUsers = (Element) dom.getFirstChild();
//找到最后一个<user>节点
NodeList nodeList = eUsers.getElementsByTagName("user");
Node lastNode=nodeList.item(nodeList.getLength()-1);
lastNode.getParentNode().removeChild(lastNode);
// /不要忘记序列化//
Transformer trans = TransformerFactory.newInstance().newTransformer();
trans.transform(new DOMSource(dom), new StreamResult("./xml/users.xml"));
}
}
结果: