隨筆-6  評論-38  文章-40  trackbacks-0

          ?

          本文主要討論了用 dom4j 解析 XML 的基礎問題,包括建立 XML 文檔,添加、修改、刪除節點,以及格式化(美化)輸出和中文問題??勺鳛?/span> 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 結合緊密,功能強大。

          posted on 2006-11-30 18:48 一手的小窩窩 閱讀(462) 評論(0)  編輯  收藏 所屬分類: JAVA
          主站蜘蛛池模板: 弥勒县| 青龙| 宜州市| 上虞市| 襄汾县| 蓬溪县| 普兰店市| 台中市| 衡南县| 巴中市| 利津县| 滨州市| 苍梧县| 珲春市| 无棣县| 诸暨市| 邢台县| 繁昌县| 益阳市| 高唐县| 蕉岭县| 灵璧县| 隆德县| 临高县| 鹤壁市| 玛曲县| 紫金县| 肃南| 广水市| 孙吴县| 疏勒县| 六安市| 双峰县| 开江县| 赣榆县| 浠水县| 北海市| 米易县| 宁明县| 安仁县| 龙海市|