本文主要討論了用dom4j解析XML的基礎問題,包括建立XML文檔,添加、修改、刪除節點,以及格式化(美化)輸出和中文問題。可作為dom4j的入門資料。
轉載自:http://jalorsoft.com/holen/
作者:陳光(holen@263.net)
時間:2004-09-11
本文主要討論了用dom4j解析XML的基礎問題,包括建立XML文檔,添加、修改、刪除節點,以及格式化(美化)輸出和中文問題。可作為dom4j的入門資料。
1. 下載與安裝
dom4j是sourceforge.net上的一個開源項目,主要用于對XML的解析。從2001年7月發布第一版以來,已陸續推出多個版本,目前最高版本為1.5。
dom4j專門針對Java開發,使用起來非常簡單、直觀,在Java界,dom4j正迅速普及。
可以到http://sourceforge.net/projects/dom4j下載其最新版。
dom4j1.5的完整版大約13M,是一個名為dom4j-1.5.zip的壓縮包,解壓后有一個dom4j-1.5.jar文件,這就是應用時需要引入的類包,另外還有一個jaxen-1.1-beta-4.jar文件,一般也需要引入,否則執行時可能拋java.lang.NoClassDefFoundError: org/jaxen/JaxenException異常,其他的包可以選擇用之。
2. 示例XML文檔(holen.xml)
為了述說方便,先看一個XML文檔,之后的操作均以此文檔為基礎。
holen.xml |
<?xml version="1.0" encoding="UTF-8"?>
<books>
<!--This is a test for dom4j, holen, 2004.9.11-->
<book show="yes">
<title>Dom4j Tutorials</title>
</book>
<book show="yes">
<title>Lucene Studing</title>
</book>
<book show="no">
<title>Lucene in Action</title>
</book>
<owner>O'Reilly</owner>
</books> |
這是一個很簡單的XML文檔,場景是一個網上書店,有很多書,每本書有兩個屬性,一個是書名[title],一個為是否展示[show],最后還有一項是這些書的擁有者[owner]信息。
3. 建立一個XML文檔
|
/**
* 建立一個XML文檔,文檔名由輸入屬性決定
* @param filename 需建立的文件名
* @return 返回操作結果, 0表失敗, 1表成功
*/
public int createXMLFile(String filename){
/** 返回操作結果, 0表失敗, 1表成功 */
int returnValue = 0;
/** 建立document對象 */
Document document = DocumentHelper.createDocument();
/** 建立XML文檔的根books */
Element booksElement = document.addElement("books");
/** 加入一行注釋 */
booksElement.addComment("This is a test for dom4j, holen, 2004.9.11");
/** 加入第一個book節點 */
Element bookElement = booksElement.addElement("book");
/** 加入show屬性內容 */
bookElement.addAttribute("show","yes");
/** 加入title節點 */
Element titleElement = bookElement.addElement("title");
/** 為title設置內容 */
titleElement.setText("Dom4j Tutorials");
/** 類似的完成后兩個book */
bookElement = booksElement.addElement("book");
bookElement.addAttribute("show","yes");
titleElement = bookElement.addElement("title");
titleElement.setText("Lucene Studing");
bookElement = booksElement.addElement("book");
bookElement.addAttribute("show","no");
titleElement = bookElement.addElement("title");
titleElement.setText("Lucene in Action");
/** 加入owner節點 */
Element ownerElement = booksElement.addElement("owner");
ownerElement.setText("O'Reilly");
try{
/** 將document中的內容寫入文件中 */
XMLWriter writer = new XMLWriter(new FileWriter(new File(filename)));
writer.write(document);
writer.close();
/** 執行成功,需返回1 */
returnValue = 1;
}catch(Exception ex){
ex.printStackTrace();
}
return returnValue;
} |
說明:
Document document = DocumentHelper.createDocument();
通過這句定義一個XML文檔對象。
Element booksElement = document.addElement("books");
通過這句定義一個XML元素,這里添加的是根節點。
Element有幾個重要的方法:
l addComment:添加注釋
l addAttribute:添加屬性
l addElement:添加子元素
最后通過XMLWriter生成物理文件,默認生成的XML文件排版格式比較亂,可以通過OutputFormat類的createCompactFormat()方法或createPrettyPrint()方法格式化輸出,默認采用createCompactFormat()方法,顯示比較緊湊,這點將在后面詳細談到。
生成后的holen.xml文件內容如下:
|
<?xml version="1.0" encoding="UTF-8"?>
<books><!--This is a test for dom4j, holen, 2004.9.11--><book show="yes"><title>Dom4j Tutorials</title></book><book show="yes"><title>Lucene Studing</title></book><book show="no"><title>Lucene in Action</title></book><owner>O'Reilly</owner></books> |
4. 修改XML文檔
有三項修改任務,依次為:
l 如果book節點中show屬性的內容為yes,則修改成no
l 把owner項內容改為Tshinghua,并添加date節點
l 若title內容為Dom4j Tutorials,則刪除該節點
|
/**
* 修改XML文件中內容,并另存為一個新文件
* 重點掌握dom4j中如何添加節點,修改節點,刪除節點
* @param filename 修改對象文件
* @param newfilename 修改后另存為該文件
* @return 返回操作結果, 0表失敗, 1表成功
*/
public int ModiXMLFile(String filename,String newfilename){
int returnValue = 0;
try{
SAXReader saxReader = new SAXReader();
Document document = saxReader.read(new File(filename));
/** 修改內容之一: 如果book節點中show屬性的內容為yes,則修改成no */
/** 先用xpath查找對象 */
List list = document.selectNodes("/books/book/@show" );
Iterator iter = list.iterator();
while(iter.hasNext()){
Attribute attribute = (Attribute)iter.next();
if(attribute.getValue().equals("yes")){
attribute.setValue("no");
}
}
/**
* 修改內容之二: 把owner項內容改為Tshinghua
* 并在owner節點中加入date節點,date節點的內容為2004-09-11,還為date節點添加一個屬性type
*/
list = document.selectNodes("/books/owner" );
iter = list.iterator();
if(iter.hasNext()){
Element ownerElement = (Element)iter.next();
ownerElement.setText("Tshinghua");
Element dateElement = ownerElement.addElement("date");
dateElement.setText("2004-09-11");
dateElement.addAttribute("type","Gregorian calendar");
}
/** 修改內容之三: 若title內容為Dom4j Tutorials,則刪除該節點 */
list = document.selectNodes("/books/book");
iter = list.iterator();
while(iter.hasNext()){
Element bookElement = (Element)iter.next();
Iterator iterator = bookElement.elementIterator("title");
while(iterator.hasNext()){
Element titleElement=(Element)iterator.next();
if(titleElement.getText().equals("Dom4j Tutorials")){
bookElement.remove(titleElement);
}
}
}
try{
/** 將document中的內容寫入文件中 */
XMLWriter writer = new XMLWriter(new FileWriter(new File(newfilename)));
writer.write(document);
writer.close();
/** 執行成功,需返回1 */
returnValue = 1;
}catch(Exception ex){
ex.printStackTrace();
}
}catch(Exception ex){
ex.printStackTrace();
}
return returnValue;
}
|
說明:
List list = document.selectNodes("/books/book/@show" );
list = document.selectNodes("/books/book");
上述代碼通過xpath查找到相應內容。
通過setValue()、setText()修改節點內容。
通過remove()刪除節點或屬性。
5. 格式化輸出和指定編碼
默認的輸出方式為緊湊方式,默認編碼為UTF-8,但對于我們的應用而言,一般都要用到中文,并且希望顯示時按自動縮進的方式的顯示,這就需用到OutputFormat類。
|
/**
* 格式化XML文檔,并解決中文問題
* @param filename
* @return
*/
public int formatXMLFile(String filename){
int returnValue = 0;
try{
SAXReader saxReader = new SAXReader();
Document document = saxReader.read(new File(filename));
XMLWriter writer = null;
/** 格式化輸出,類型IE瀏覽一樣 */
OutputFormat format = OutputFormat.createPrettyPrint();
/** 指定XML編碼 */
format.setEncoding("GBK");
writer= new XMLWriter(new FileWriter(new File(filename)),format);
writer.write(document);
writer.close();
/** 執行成功,需返回1 */
returnValue = 1;
}catch(Exception ex){
ex.printStackTrace();
}
return returnValue;
} |
說明:
OutputFormat format = OutputFormat.createPrettyPrint();
這句指定了格式化的方式為縮進式,則非緊湊式。
format.setEncoding("GBK");
指定編碼為GBK。
XMLWriter writer = new XMLWriter(new FileWriter(new File(filename)),format);
這與前面兩個方法相比,多加了一個OutputFormat對象,用于指定顯示和編碼方式。
6. 完整的類代碼
前面提出的方法都是零散的,下面給出完整類代碼。
Dom4jDemo.java |
package com.holen.dom4j;
import java.io.File;
import java.io.FileWriter;
import java.util.Iterator;
import java.util.List;
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
/**
* @author Holen Chen
*/
public class Dom4jDemo {
public Dom4jDemo() {
}
public int createXMLFile(String filename){…}
public int ModiXMLFile(String filename,String newfilename){…}
public int formatXMLFile(String filename){…}
public static void main(String[] args) {
Dom4jDemo temp = new Dom4jDemo();
System.out.println(temp.createXMLFile("d://holen.xml")); System.out.println(temp.ModiXMLFile("d://holen.xml","d://holen2.xml"));
System.out.println(temp.formatXMLFile("d://holen2.xml"));
}
} |
說明:
main()方法中依次調用三個方法,第一個方法用于生成holen.xml,第二個方法用于修改holen.xml,并且修改后的內容另存為holen2.xml,第三個方法將holen2.xml格式化縮進式輸出,并指定編碼方式為GBK。
重新格式化后holen2.xml文件顯示如下:

項目視圖供參考:

7. 總結
總的來說,dom4j的使用是很簡單的,而且與Java結合緊密,功能強大。