很多朋友對DOM有感冒,這裏我花了一些時間寫了一個小小的教程,這個能看懂,會操作了,我相信基於DOM的其它API(如JDOM,DOM4J等)一般不會有什麼問題。
後附java代碼,也可以下載(可點擊這裏入下載)導入到Eclipse或MyEclipse。
Node和Element的關係
- Element是Node的子接口,所以Element的方法要比Node方法要多,這樣的話使用起來比較方便,一般情況我們都把節點轉換成元素(或者叫標籤,即Element);
- Element是Node的子類型:
比如我們運行實例中的readByNode(Node node)方法,如果把類型斷碼if (node.getNodeType()==node.ELEMENT_NODE)註釋掉,你會發現會輸出以下內容:
節點名:#document
節點類型:9
節點值:null
節點名:students
節點類型:1
節點值:null
節點名:#text
節點類型:3
節點值:
節點名:student
節點類型:1
節點值:null
節點名:#text
節點類型:3
節點值:
------部分控制檯內容已省略------
輸出內容包括文本類型(DOM會把空格也當做類型)和document類型及元素類型,如果只查找Element類型,可以使用判斷Node類型,這個我們一定要注意!
我們從結果可以看出來 Element實際上是”<>”內的值。
節點類型常量字段值可對照Java API文檔的Node”常量字段值“查看:
修改xml後需要使用Transformer更新到xml文件中
因爲DOM修改是在內存中修改,要更新到xml文件中,必須使用Transformer寫入。除讀以外,其它的增、刪、改這些更新數據的操作必須Transformer更新到xml文件。
什麼時候使用item(0)?
當我們使用通過getElementsByTagName得到的是子元素的集合,如果這個子元素集合中只有一個元素時我們可以使用item(0),當然我們指定item(0),因爲item(0)是第一個元素集合中的第一個元素。
如何刪除節點?
首先要獲得要刪除的節點,然後再得到其父節點,再使用父節點的removeChild方法刪除要刪除節點,所以刪除是不能“自殺”。
如何創建節點?
首先使用DOM的createElement方法創建各個元素,然後通過appendChild方法讓各個之間建立父子關係,這個關係不一定要從根節點開始,要看你如何增加,是否準確的找到插入位置就可以了。
-----------------------------------以下爲xml代碼-----------------------------------
<?xml version="1.0" encoding="utf-8" ?>
<students>
<student id="001" sex="男">
<name>周星馳</name>
<age>23</age>
<intro>這是一位成績很好的學生</intro>
</student>
<student id="002" sex="男">
<name>劉德華</name>
<age>32</age>
<intro>他綜合能力很優秀</intro>
</student>
<student id="003" sex="女">
<name>周惠敏</name>
<age>31</age>
<intro>長得漂亮</intro>
</student>
<student id="004" sex="男">
<name>王五</name>
<age>37</age>
<intro>成績有點差</intro>
</student>
<student id="005" sex="男">
<name>張三丰</name>
<age>26</age>
<intro>經常逃課</intro>
</student>
</students>
-----------------------------------以下爲java代碼-----------------------------------
package com.xmltest;
import java.io.File;
import java.io.IOException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
// 注意不要導錯包了
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
/**
* <b>項目:</b>使用DOM進行xml文檔的crud(增刪改查)操作<br />
* <b>文件名:</b> Xml_Crud.java<br />
* <b>類名:</b> Xml_Crud<br />
* <b>包:</b> com.xmltest<br />
* <b>描述:</b> 一個xml簡單的crud操作<br />
* <hr />
* <div align="left"><font color="#FF0000">xml的crud增刪改查操作
* <hr />
* <b>時間:</b> 2014-12-1 上午9:45:45<br />
* <b>Copyright:</b> 2014<br />
* @author javalittleman
* @version V1.0
*/
public class Xml_Crud {
public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException, TransformerException {
File file = new File("src/student.xml");
Document doc=doc(file);
// 以下爲【增\刪\改\查】操作
// 【查】一:通過node遍歷
// readByNode(doc);
// 【查】二:通過傳入第幾個學生獲得該學生下的所有信息
// read(doc, 1);
/* 【查】三:
* 通過傳入的學生姓名獲得該學生的所有信息
* 傳入的爲name元素的文本值
*/
// read(doc,"劉德華");
// 【刪】一:通過序號刪除
// delete(doc, 1);
// 【刪】二:通過學生姓名刪除
// delete(doc, "張三丰");
// 【增】:向xml中增加一個學生
// creat(doc, "趙五", "男", "007", "21", "成績一般,上課不太專心");
// 【改】一:根據student的id屬性修改xml文件
updata(doc, "003", "周小明");
}
public static void readByNode(Node node){
// 遍歷時會把所有的text節點都輸出
// 加上node.getNodeType()==node.ELEMENT_NODE可輸出元素節點
if (node.getNodeType()==node.ELEMENT_NODE) {
System.out.println("節點名:" + node.getNodeName());
System.out.println("節點類型:" + node.getNodeType());
System.out.println("節點值:" + node.getNodeValue());
}
NodeList nodeList=node.getChildNodes();
for (int i = 0; i < nodeList.getLength(); i++) {
Node n = nodeList.item(i);
readByNode(n);
}
}
/**
* <b>標題:</b> doc 方法 <br />
* <b>描述:</b>生成DOM樹的方法 <br />
* <b>返回類型:</b>Document<br />
*
* @param file
* 傳入一個文件,在本實例中使用xml文件傳
* @return 返回一個DOM樹
* @throws ParserConfigurationException
* 拋出解析配置錯誤異常
* @throws SAXException
* 拋出SAX異常
* @throws IOException
* 招聘IO異常
*/
public static Document doc(File file) throws ParserConfigurationException, SAXException, IOException{
// 創建解析工廠
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
// 創建解析器
DocumentBuilder db = dbf.newDocumentBuilder();
// 創建xml文件,得到一個DOM樹
Document doc = db.parse(file);
// 返回DOM樹
return doc;
}
/**
* <b>標題:</b> tran 方法 <br />
* <b>描述:</b>用於將內存中的DOM寫入xml文件中 <br />
* <b>返回類型:</b>void<br />
* @param doc 內存中的DOM樹
* @param file 目標文件
* @throws TransformerException 拋出轉換異常
*/
public static void tran(Document doc,File file) throws TransformerException{
TransformerFactory tff = TransformerFactory.newInstance();
Transformer tf = tff.newTransformer();
tf.setOutputProperty(OutputKeys.ENCODING, "utf-8");
DOMSource xmlSource = new DOMSource(doc);
StreamResult streamresult = new StreamResult(file);
tf.transform(xmlSource, streamresult);
}
/**
* <b>標題:</b> 【查】一:read 方法一 <br />
* <b>描述:</b>通過學生的序號讀出學生信息 <br />
* <b>返回類型:</b>void<br />
* @param doc DOM樹
* @param itemNum 傳入的第itemNum個學生
* @throws 無
*/
public static void read(Document doc,int itemNum){
//獲取第itemNum-1個student元素,比如itemNum爲我設1,那麼就是第0個元素
Element student=(Element) doc.getElementsByTagName("student").item(itemNum-1);
if (student!=null) {
// 獲得其id屬性值
String id=student.getAttribute("id");
// 獲得其sex屬性值
String sex=student.getAttribute("sex");
// 分別獲得第itemNum-1個元素下的name、age、intro的文本值
// 因爲第itemNum-1個student下只有一個name元素,所以使用item(0),age和intro亦然
String name = (String) student.getElementsByTagName("name").item(0).getTextContent();
String age = (String) student.getElementsByTagName("age").item(0).getTextContent();
String intro = (String) student.getElementsByTagName("intro").item(0).getTextContent();
// 分別打印id、sex、name、intro值
System.out.println(id + " " + name + " " + sex + " " + age + "歲 "+intro);
}else {
System.out.println("第“"+itemNum+"位”學生不存在");
}
}
/**
* <b>標題:</b> 【查】二: read 方法二 <br />
* <b>描述:</b>通過給出的學生姓名讀取xml <br />
* <b>返回類型:</b>void<br />
* @param doc DOM樹
* @param studentNmae 傳入學生姓名
* @throws 無
*/
public static void read(Document doc, String studentNmae) {
//首先獲得student元素
NodeList student = doc.getElementsByTagName("student");
/*
* 遍歷所有student節點下,找出其下的name元素
* 是否有與傳入studentName相同
* 如果有就獲取其id、sex、name、age、intro
* --------思路--------
* 從遍歷中獲得name的文本爲對應給出的studentName值後,取得name文本值
* 再獲得其父節點,然後纔得到id、sex、age、intro的文本值
*/
boolean isFund = false;
String name=null;
String sex=null;
String id=null;
String age=null;
String intro=null;
for (int i = 0; i < student.getLength(); i++) {
Element ele = (Element) student.item(i);
Element name_ele=(Element) ele.getElementsByTagName("name").item(0);
name=name_ele.getTextContent();
if (studentNmae.equals(name_ele.getTextContent())) {
// 如果找到我們要找的學生姓名就取得其父元素,即student元素
Element me=(Element) name_ele.getParentNode();
sex=me.getAttribute("sex");
id=me.getAttribute("id");
// 因爲每個student下只有一個age和intro元素,所以採用item(0)
age= me.getElementsByTagName("age").item(0).getTextContent();
intro=me.getElementsByTagName("intro").item(0).getTextContent();
isFund=true;
break;
}
}
if (isFund) {
System.out.println(id + " " + name + " " + sex + " " + age + "歲 " + intro);
} else {
System.out.println("沒有找到“" + studentNmae + "”這個學生");
}
}
/**
* <b>標題:</b>【刪】一: delete 方法一 <br />
* <b>描述:</b>根據傳入的第幾個元素進行刪除 <br />
* <b>返回類型:</b>void<br />
* @param doc 傳入的DOM樹
* @param studentNum 傳入的第幾個學生,也就是第幾個元素
* @throws TransformerException 拋出轉換異常
*/
public static void delete(Document doc,int studentNum) throws TransformerException{
Element ele = (Element) doc.getElementsByTagName("student").item(studentNum-1);
if (ele != null) {
ele.getParentNode().removeChild(ele);
System.out.println("刪除成功");
} else {
System.out.println("該第" + studentNum + "位不存在,不能刪除");
}
tran(doc, new File("src/student.xml"));
}
/**
* <b>標題:</b>【刪】二: delete 方法二 <br />
* <b>描述:</b>給出某個學生姓名進行刪,即根據文本值刪除 <br />
* <b>返回類型:</b>void<br />
* @param doc
* @param studentName
* @throws TransformerException
* @throws 無
*/
public static void delete(Document doc,String studentName) throws TransformerException{
NodeList nodelist = doc.getElementsByTagName("name");
boolean isFund=false;
Element ele=null;
for (int i = 0; i < nodelist.getLength(); i++) {
ele = (Element) nodelist.item(i);
if (studentName.equals(ele.getTextContent())) {
isFund=true;
}
}
if (isFund) {
ele.getParentNode().getParentNode().removeChild(ele.getParentNode());
tran(doc, new File("src/student.xml"));
System.out.println("已經刪除“"+studentName+"”這位同學的信息");
} else {
System.out.println("找不到“" + studentName + "”這位學生,不能刪除");
}
}
/**
* <b>標題:</b>【增】 updata 方法 <br />
* <b>描述:</b>向xml文件中增加信息 <br />
* <b>返回類型:</b>void<br />
* @param doc 傳入的DOM樹
* @param name 姓名標籤
* @param sex student標籤的性別屬性
* @param id student標籤的id屬性
* @param age 年齡標籤
* @param intro 介紹標籤
* @throws TransformerException
*/
public static void creat(Document doc,String name,String sex,String id,String age,String intro) throws TransformerException{
// 找到根節點,根節點只有一個所以使用item(0)
Element root=(Element) doc.getElementsByTagName("students").item(0);
// 創建各個節點
Element ele_student=doc.createElement("student");
ele_student.setAttribute("id", id);
ele_student.setAttribute("sex", sex);
Element ele_name=doc.createElement("name");
ele_name.setTextContent(name);
Element ele_age=doc.createElement("age");
ele_age.setTextContent(age);
Element ele_intro=doc.createElement("intro");
ele_intro.setTextContent(intro);
// 使用appenChild方法增加父子關係
root.appendChild(ele_student);
ele_student.appendChild(ele_name);
ele_student.appendChild(ele_age);
ele_student.appendChild(ele_intro);
// 寫入xml文件
tran(doc, new File("src/student.xml"));
System.out.println("“"+name+"”同學的信息已經增加成功!");
}
/**
* <b>標題:</b>【改】: updata 方法<br />
* <b>描述:</b>根據標籤的屬性值修改xml文件 <br />
* 根據標籤的文本值去修改其文本值這裏就省略了<br />
* <b>返回類型:</b>void<br />
* @param doc 傳入DOM樹
* @param id 傳入student的id屬性值
* @param newName 傳入新學生姓名
* @throws TransformerException 拋出轉換異常
*/
public static void updata(Document doc,String id,String newName) throws TransformerException{
boolean isFund=false;
// 獲得student節點集合
NodeList stu=doc.getElementsByTagName("student");
// 遍歷student集合,並從中獲得其id屬性爲傳入的id值的元素,然後修改其元素下的name的文本值
for (int i = 0; i < stu.getLength(); i++) {
Element ele_stu=(Element) stu.item(i);
if (id.equals(ele_stu.getAttribute("id"))) {
ele_stu.getElementsByTagName("name").item(0).setTextContent(newName);
isFund=true;
break;
}
}
if (isFund) {
// 寫入xml文件
tran(doc, new File("src/student.xml"));
System.out.println("修改成功");
} else {
System.out.println("不存在這個“" + id + "”ID屬性值,修改失敗!!!");
}
}
}