隨筆-6  評(píng)論-38  文章-40  trackbacks-0

          ?

          本文主要討論了用 dom4j 解析 XML 的基礎(chǔ)問(wèn)題,包括建立 XML 文檔,添加、修改、刪除節(jié)點(diǎn),以及格式化(美化)輸出和中文問(wèn)題。可作為 dom4j 的入門資料。

          ?

          1. 下載與安裝

          ?

          dom4j sourceforge.net 上的一個(gè)開源項(xiàng)目,主要用于對(duì) XML 的解析。從 2001 7 月發(fā)布第一版以來(lái),已陸續(xù)推出多個(gè)版本,目前最高版本為 1.5

          dom4j 專門針對(duì) Java 開發(fā),使用起來(lái)非常簡(jiǎn)單、直觀,在 Java 界, dom4j 正迅速普及。

          ?

          可以到 http://sourceforge.net/projects/dom4j 下載其最新版。

          ?

          dom4j1.5 的完整版大約 13M ,是一個(gè)名為 dom4j-1.5.zip 的壓縮包,解壓后有一個(gè) dom4j-1.5.jar 文件,這就是應(yīng)用時(shí)需要引入的類包,另外還有一個(gè) jaxen-1.1-beta-4.jar 文件,一般也需要引入,否則執(zhí)行時(shí)可能拋 java.lang.NoClassDefFoundError: org/jaxen/JaxenException 異常,其他的包可以選擇用之。

          ?

          2. 示例 XML 文檔( holen.xml

          ?

          為了述說(shuō)方便,先看一個(gè) XML 文檔,之后的操作均以此文檔為基礎(chǔ)。

          ?

          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>

          ?

          這是一個(gè)很簡(jiǎn)單的 XML 文檔,場(chǎng)景是一個(gè)網(wǎng)上書店,有很多書,每本書有兩個(gè)屬性,一個(gè)是書名 [title] ,一個(gè)為是否展示 [show] ,最后還有一項(xiàng)是這些書的擁有者 [owner] 信息。

          ?

          3. 建立一個(gè) XML 文檔

          ?

          ?

          ??? /**

          ??? ? * 建立一個(gè) XML 文檔 , 文檔名由輸入屬性決定

          ??? ? * @param filename 需建立的文件名

          ??? ? * @return 返回操作結(jié)果 , 0 表失敗 , 1 表成功

          ??? ? */

          ??? public int createXMLFile(String filename){

          ?????? /** 返回操作結(jié)果 , 0 表失敗 , 1 表成功 */

          ?????? int returnValue = 0;

          ?????? /** 建立 document 對(duì)象 */

          ?????? Document document = DocumentHelper.createDocument();

          ?????? /** 建立 XML 文檔的根 books */

          ?????? Element booksElement = document.addElement( "books" );

          ?????? /** 加入一行注釋 */

          ?????? booksElement.addComment( "This is a test for dom4j, holen, 2004.9.11" );

          ?????? /** 加入第一個(gè) book 節(jié)點(diǎn) */

          ?????? Element bookElement = booksElement.addElement( "book" );

          ?????? /** 加入 show 屬性內(nèi)容 */

          ?????? bookElement.addAttribute( "show" , "yes" );

          ?????? /** 加入 title 節(jié)點(diǎn) */

          ?????? Element titleElement = bookElement.addElement( "title" );

          ?????? /** title 設(shè)置內(nèi)容 */

          ?????? titleElement.setText( "Dom4j Tutorials" );

          ??????

          ?????? /** 類似的完成后兩個(gè) 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 節(jié)點(diǎn) */

          ?????? Element ownerElement = booksElement.addElement( "owner" );

          ?????? ownerElement.setText( "O'Reilly" );

          ??????

          ?????? try {

          ?????????? /** document 中的內(nèi)容寫入文件中 */

          ?????????? XMLWriter writer = new XMLWriter( new FileWriter( new File(filename)));

          ?????????? writer.write(document);

          ?????????? writer.close();

          ?????????? /** 執(zhí)行成功 , 需返回 1 */

          ?????????? returnValue = 1;

          ?????? } catch (Exception ex){

          ?????????? ex.printStackTrace();

          ?????? }

          ?????????????

          ?????? return returnValue;

          ??? }

          ?

          說(shuō)明:

          Document document = DocumentHelper.createDocument();

          通過(guò)這句定義一個(gè) XML 文檔對(duì)象。

          ?

          Element booksElement = document.addElement("books");

          通過(guò)這句定義一個(gè) XML 元素,這里添加的是根節(jié)點(diǎn)。

          Element 有幾個(gè)重要的方法:

          l???????? addComment :添加注釋

          l???????? addAttribute :添加屬性

          l???????? addElement :添加子元素

          ?

          最后通過(guò) XMLWriter 生成物理文件,默認(rèn)生成的 XML 文件排版格式比較亂,可以通過(guò) OutputFormat 類的 createCompactFormat() 方法或 createPrettyPrint() 方法格式化輸出,默認(rèn)采用 createCompactFormat() 方法,顯示比較緊湊,這點(diǎn)將在后面詳細(xì)談到。

          ?

          生成后的 holen.xml 文件內(nèi)容如下:

          ?

          ?

          <?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 文檔

          ?

          有三項(xiàng)修改任務(wù),依次為:

          l???????? 如果 book 節(jié)點(diǎn)中 show 屬性的內(nèi)容為 yes, 則修改成 no

          l???????? owner 項(xiàng)內(nèi)容改為 Tshinghua ,并添加 date 節(jié)點(diǎn)

          l???????? title 內(nèi)容為 Dom4j Tutorials, 則刪除該節(jié)點(diǎn)

          ?

          ?

          ??? /**

          ??? ? * 修改 XML 文件中內(nèi)容 , 并另存為一個(gè)新文件

          ??? ? * 重點(diǎn)掌握 dom4j 中如何添加節(jié)點(diǎn) , 修改節(jié)點(diǎn) , 刪除節(jié)點(diǎn)

          ??? ? * @param filename 修改對(duì)象文件

          ??? ? * @param newfilename 修改后另存為該文件

          ??? ? * @return 返回操作結(jié)果 , 0 表失敗 , 1 表成功

          ??? ? */

          ??? public int ModiXMLFile(String filename,String newfilename){

          ?????? int returnValue = 0;

          ?????? try {

          ?????????? SAXReader saxReader = new SAXReader();

          ?????????? Document document = saxReader.read( new File(filename));

          ?????????? /** 修改內(nèi)容之一 : 如果 book 節(jié)點(diǎn)中 show 屬性的內(nèi)容為 yes, 則修改成 no */

          ?????????? /** 先用 xpath 查找對(duì)象 */

          ?????????? 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" );

          ????????????? } ??

          ?????????? }

          ??????????

          ?????????? /**

          ?????????? ? * 修改內(nèi)容之二 : owner 項(xiàng)內(nèi)容改為 Tshinghua

          ?????????? ? * 并在 owner 節(jié)點(diǎn)中加入 date 節(jié)點(diǎn) ,date 節(jié)點(diǎn)的內(nèi)容為 2004 - 09 - 11, 還為 date 節(jié)點(diǎn)添加一個(gè)屬性 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" );

          ?????????? }

          ??????????

          ?????????? /** 修改內(nèi)容之三 : title 內(nèi)容為 Dom4j Tutorials, 則刪除該節(jié)點(diǎn) */

          ?????????? 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 中的內(nèi)容寫入文件中 */

          ????????????? XMLWriter writer = new XMLWriter( new FileWriter( new File(newfilename)));

          ????????????? writer.write(document);

          ????????????? writer.close();

          ????????????? /** 執(zhí)行成功 , 需返回 1 */

          ????????????? returnValue = 1;

          ?????????? } catch (Exception ex){

          ????????????? ex.printStackTrace();

          ?????????? }

          ??????????

          ?????? } catch (Exception ex){

          ?????????? ex.printStackTrace();

          ?????? }

          ?????? return returnValue;

          ??? }

          ???

          ?

          說(shuō)明:

          List list = document.selectNodes("/books/book/@show" );

          list = document.selectNodes("/books/book");

          上述代碼通過(guò) xpath 查找到相應(yīng)內(nèi)容。

          ?

          通過(guò) setValue () setText () 修改節(jié)點(diǎn)內(nèi)容。

          ?

          通過(guò) remove () 刪除節(jié)點(diǎn)或?qū)傩浴?/span>

          ?

          5. 格式化輸出和指定編碼

          ?

          默認(rèn)的輸出方式為緊湊方式,默認(rèn)編碼為 UTF-8 ,但對(duì)于我們的應(yīng)用而言,一般都要用到中文,并且希望顯示時(shí)按自動(dòng)縮進(jìn)的方式的顯示,這就需用到 OutputFormat 類。

          ?

          ?

          ???

          ??? /**

          ??? ? * 格式化 XML 文檔 , 并解決中文問(wèn)題

          ??? ? * @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(); ?????

          ?????????? /** 執(zhí)行成功 , 需返回 1 */

          ?????????? returnValue = 1; ????

          ?????? } catch (Exception ex){

          ?????????? ex.printStackTrace();

          ?????? }

          ?????? return returnValue;

          ??? }

          ?

          說(shuō)明:

          ?

          OutputFormat format = OutputFormat.createPrettyPrint();

          這句指定了格式化的方式為縮進(jìn)式,則非緊湊式。

          ?

          format.setEncoding("GBK");

          指定編碼為 GBK

          ?

          XMLWriter writer = new XMLWriter(new FileWriter(new File(filename)),format);

          這與前面兩個(gè)方法相比,多加了一個(gè) OutputFormat 對(duì)象,用于指定顯示和編碼方式。

          ?

          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" ));

          ??? }

          }

          ?

          說(shuō)明:

          main() 方法中依次調(diào)用三個(gè)方法,第一個(gè)方法用于生成 holen.xml ,第二個(gè)方法用于修改 holen.xml ,并且修改后的內(nèi)容另存為 holen2.xml ,第三個(gè)方法將 holen2.xml 格式化縮進(jìn)式輸出,并指定編碼方式為 GBK

          ?

          重新格式化后 holen2.xml 文件顯示如下:

          ?

          項(xiàng)目視圖供參考:

          ?

          7. 總結(jié)

          ?

          總的來(lái)說(shuō), dom4j 的使用是很簡(jiǎn)單的,而且與 Java 結(jié)合緊密,功能強(qiáng)大。

          posted on 2006-11-30 18:48 一手的小窩窩 閱讀(463) 評(píng)論(0)  編輯  收藏 所屬分類: JAVA
          主站蜘蛛池模板: 平顶山市| 吉隆县| 耒阳市| 汾西县| 阜阳市| 札达县| 河北区| 石首市| 龙岩市| 简阳市| 绵竹市| 且末县| 枣阳市| 镇坪县| 彭州市| 四川省| 闸北区| 清镇市| 南华县| 镇坪县| 远安县| 吉木乃县| 永寿县| 阳新县| 保定市| 乌苏市| 嵊泗县| 宁夏| 杭锦旗| 黔西县| 乌鲁木齐县| 芮城县| 常德市| 邯郸市| 福鼎市| 桐乡市| 永登县| 银川市| 丰镇市| 唐山市| 杨浦区|