DOM4J dom4j.org 出品的一個(gè)開源 XML 解析包,它的網(wǎng)站中這樣定義:

 

 

 

 

 

 

Dom4j is an easy to use, open source library for working with XML, XPath and XSLT on the Java platform using the Java Collections Framework and with full support for DOM, SAX and JAXP.

 

 

 

 

 

 

Dom4j 是一個(gè)易用的、開源的庫,用于 XML XPath XSLT 。它應(yīng)用于 Java 平臺,采用了 Java 集合框架并完全支持 DOM SAX JAXP

 

 

 

 

 

 

Dom4j.jar 包括 dom4j 類和 XPath 引擎,但是不含 SAX DOM 接口。最好使用 1.5 的版本 , 有兩個(gè)包文件 , dom4j-1.5.jar dom4j-full.jar ,目前 1.6 的還不穩(wěn)定。下載網(wǎng)址: http://sourceforge.net/projects/dom4j

 

 

 

 

 

 

 

 

 

 

 

 

它的主要接口都在 org.dom4j 這個(gè)包里定義:

 

 

 

 

 

 

Attribute

 

 

 

 

 

 

Attribute 定義了 XML 的屬性

 

 

 

 

 

 

Branch

 

 

 

 

 

 

Branch 為能夠包含子節(jié)點(diǎn)的節(jié)點(diǎn)如 XML 元素 (Element) 和文檔 (Docuemnts) 定義了一個(gè)公共的行為,

 

 

 

 

 

 

CDATA

 

 

 

 

 

 

CDATA 定義了 XML CDATA 區(qū)域

 

 

 

 

 

 

CharacterData

 

 

 

 

 

 

CharacterData 是一個(gè)標(biāo)識借口,標(biāo)識基于字符的節(jié)點(diǎn)。如 CDATA Comment, Text.

 

 

 

 

 

 

Comment

 

 

 

 

 

 

Comment 定義了 XML 注釋的行為

 

 

 

 

 

 

Document

 

 

 

 

 

 

定義了 XML 文檔

 

 

 

 

 

 

DocumentType

 

 

 

 

 

 

DocumentType 定義 XML DOCTYPE 聲明

 

 

 

 

 

 

Element

 

 

 

 

 

 

Element 定義 XML 元素

 

 

 

 

 

 

ElementHandler

 

 

 

 

 

 

ElementHandler 定義了 Element 對象的處理器

 

 

 

 

 

 

ElementPath

 

 

 

 

 

 

ElementHandler 使用,用于取得當(dāng)前正在處理的路徑層次信息

 

 

 

 

 

 

Entity

 

 

 

 

 

 

Entity 定義 XML entity

 

 

 

 

 

 

Node

 

 

 

 

 

 

Node 為所有的 dom4j XML 節(jié)點(diǎn) 定義了多態(tài)行為

 

 

 

 

 

 

NodeFilter

 

 

 

 

 

 

NodeFilter 定義了在 dom4j 節(jié)點(diǎn)中產(chǎn)生的一個(gè)濾鏡或謂詞的行為( predicate

 

 

 

 

 

 

ProcessingInstruction

 

 

 

 

 

 

ProcessingInstruction 定義 XML 處理指令 .

 

 

 

 

 

 

Text

 

 

 

 

 

 

Text 定義 XML 文本節(jié)點(diǎn) .

 

 

 

 

 

 

Visitor

 

 

 

 

 

 

Visitor 用于實(shí)現(xiàn) Visitor 模式 .

 

 

 

 

 

 

XPath

 

 

 

 

 

 

XPath 在分析一個(gè)字符串后會提供一個(gè) XPath 表達(dá)式

 

 

 

 

 

 

 

 

 

 

1.              讀取并解析XML文檔:

讀寫XML文檔主要依賴于org.dom4j.io包,其中提供DOMReader和SAXReader兩類不同方式,而調(diào)用方式是一樣的。這就是依靠接口的好處。  

//  從文件讀取XML,輸入文件名,返回XML文檔

    
public  Document read(String fileName)  throws  MalformedURLException, DocumentException  {

       SAXReader reader 
=   new  SAXReader();

       Document document 
=  reader.read( new  File(fileName));

       
return  document;

    }


 

其中,reader的read方法是重載的,可以從InputStream, File, Url等多種不同的源來讀取。得到的Document對象就帶表了整個(gè)XML。

根據(jù)本人自己的經(jīng)驗(yàn),讀取的字符編碼是按照XML文件頭定義的編碼來轉(zhuǎn)換。如果遇到亂碼問題,注意要把各處的編碼名稱保持一致即可。

2.    取得Root節(jié)點(diǎn)

讀取后的第二步,就是得到Root節(jié)點(diǎn)。熟悉XML的人都知道,一切XML分析都是從Root元素開始的。

 

   
public Element getRootElement(Document doc){

       
return doc.getRootElement();

    }

















 

3.    遍歷XML樹

DOM4J提供至少3種遍歷節(jié)點(diǎn)的方法:

1) 枚舉(Iterator)

 

    // 枚舉所有子節(jié)點(diǎn)

  

  for ( Iterator i = root.elementIterator(); i.hasNext(); ) {      
        Element element 
= (Element) i.next();       // do something  
      }

    // 枚舉名稱為foo的節(jié)點(diǎn)

   

 for ( Iterator i = root.elementIterator(foo); i.hasNext();) {     
       Element foo 
= (Element) i.next();      
  
// do something    }

    // 枚舉屬性

   

 for ( Iterator i = root.attributeIterator(); i.hasNext(); ) {      
      Attribute attribute 
= (Attribute) i.next();       //
 do something    }



2)遞歸

遞歸也可以采用Iterator作為枚舉手段,但文檔中提供了另外的做法

 

   

public void treeWalk() {       
    treeWalk(getRootElement());   
 }
   
public void treeWalk(Element element) {     
    
for (int i = 0, size = element.nodeCount(); i < size; i++)   
  
{    Node node = element.node(i);           
         if (node instanceof Element)
 
{              treeWalk((Element) node);           } 
        else // do something.          
 }       }}


 

4. XPath支持

    DOM4J對XPath有良好的支持,如訪問一個(gè)節(jié)點(diǎn),可直接用XPath選擇。

 

  

 public void bar(Document document) {      
   List list 
= document.selectNodes( //foo/bar );      
   Node node = document.selectSingleNode(
//foo/bar/author);        
   String name = node.valueOf( @name );     }


 


例如,如果你想查找XHTML文檔中所有的超鏈接,下面的代碼可以實(shí)現(xiàn):

 

   

 public void findLinks(Document document) throws DocumentException {     
        List list 
= document.selectNodes( //a/@href );        
        for (Iterator iter = list.iterator(); iter.hasNext(); ) {            
             Attribute attribute = (Attribute) iter.next();           
             String url = attribute.getValue();        }     }


 

5. 字符串與XML的轉(zhuǎn)換

有時(shí)候經(jīng)常要用到字符串轉(zhuǎn)換為XML或反之,

 
   
 // XML轉(zhuǎn)字符串   
     Document document = ;    
     String text = document.asXML();
// 字符串轉(zhuǎn)XML    
     String text = <person> <name>James</name> </person>;    
     Document document = DocumentHelper.parseText(text);












 

7. 創(chuàng)建XML

  一般創(chuàng)建XML是寫文件前的工作,這就像StringBuffer一樣容易。

 

   

 public Document createDocument() {     
      Document document 
= DocumentHelper.createDocument();      
      Element root 
= document.addElement(root);       
       Element author1 
= root  .addElement(author) .addAttribute(name, James) .addAttribute(location, UK) .addText(James Strachn);  
       Element author2 
= root  .addElement(author) .addAttribute(name, Bob) .addAttribute(location, US) .addText(Bob McWhirter);       
     return document;

如果你想改變輸出的格式,比如美化輸出或縮減格式,可以用XMLWriter類



public void write(Document document) throws IOException {       // 指定文件      
           XMLWriter writer = new XMLWriter(  new FileWriter( output.xml )       );       
           writer.write( document );       
           writer.close();
       
    // 美化格式       
    OutputFormat format = OutputFormat.createPrettyPrint();      
     writer = new XMLWriter( System.out, format );       
     writer.write( document );      
 
// 縮減格式       
     format = OutputFormat.createCompactFormat();       
     writer = new XMLWriter( System.out, format );       
    writer.write( document );    }



一、          使用

 

 

 

 

 

1、創(chuàng)建XML文檔

 

 

 

 

 

 

dom4j創(chuàng)建xmlgenerateDocument()需要以下四步:創(chuàng)建文檔、添加根元素、添加子元素、添加元素內(nèi)容、寫XML文件。

 

 

 

 

 

 

使用的類有org.dom4j.Document,org.dom4j.DocumentHelper,

 

 

 

 

 

 

org.dom4j.Element 類。

 

 

 

 

 

 

代碼如下:

 

 

 

 

 

 

import org.dom4j.Document;   //導(dǎo)入dom4j API

 

 

 

 

 

 

import org.dom4j.DocumentException;

 

 

 

 

 

 

import org.dom4j.Element;

 

 

 

 

 

 

import org.dom4j.Attribute;

 

 

 

 

 

 

import org.dom4j.DocumentHelper;

 

 

 

 

 

 

import org.dom4j.io.OutputFormat;

 

 

 

 

 

 

import org.dom4j.io.XMLWriter;

 

 

 

 

 

 

import org.dom4j.io.SAXReader;

 

 

 

 

 

 

import java.io.*;

 

 

 

 

 

 

import java.util.List;

 

 

 

 

 

 

import java.util.Iterator;

 

 

 

 

 

 

 

 

 

 

class Rt

 

 

 

 

 

{

 

public Document generateDocument()

 

 

 

 

 

 

{

 

 

 

 

 

 

     //使用DocumentHelper 類創(chuàng)建一個(gè)文檔實(shí)例。DocumentHelper 是生成XML 文檔節(jié)點(diǎn)的dom4j API 工廠類。

 

 

 

 

 

 

     Document document = DocumentHelper.createDocument();

 

 

 

 

 

 

    

 

 

 

 

 

 

     //使用addElement() 方法創(chuàng)建根元素catalog addElement() 用于向XML 文檔中增加元素。

 

 

 

 

 

 

     Element catalogElement = document.addElement("catalog");

 

 

 

 

 

 

    

 

 

 

 

 

 

     //catalog 元素中使用addComment() 方法添加注釋“An XML catalog”。

 

 

 

 

 

 

     catalogElement.addComment("An XML Catalog");

 

 

 

 

 

 

    

 

 

 

 

 

 

     //catalog 元素中使用addProcessingInstruction() 方法增加一個(gè)處理指令。

 

 

 

 

 

 

     catalogElement.addProcessingInstruction("target","text");

 

 

 

 

 

 

    

 

 

 

 

 

 

     //catalog 元素中使用addElement() 方法增加journal 元素。

 

 

 

 

 

 

     Element journalElement =  catalogElement.addElement("journal");

 

 

 

 

 

 

    

 

 

 

 

 

 

     //使用addAttribute() 方法向journal 元素添加title publisher 屬性

 

 

 

 

 

 

     journalElement.addAttribute("title", "XML Zone");

 

 

 

 

 

 

     journalElement.addAttribute("publisher", "IBM developerWorks");

 

 

 

 

 

 

 

 

 

 

 

 

     //journal 元素中添加article 元素,使用addAttribute()方法向article元素添加level,date屬性

 

 

 

 

 

 

     Element articleElement=journalElement.addElement("article");

 

 

 

 

 

 

     articleElement.addAttribute("level", "Intermediate");

 

 

 

 

 

 

     articleElement.addAttribute("date", "December-2001");

 

 

 

 

 

 

    

 

 

 

 

 

 

     //article元素中添加title元素

 

 

 

 

 

 

     Element  titleElement=articleElement.addElement("title");

 

 

 

 

 

 

     //使用setText() 方法設(shè)置article 元素的文本

 

 

 

 

 

 

     titleElement.setText("Java configuration with XML Schema");

 

 

 

 

 

 

     //article元素中添加author元素

 

 

 

 

 

 

     Element authorElement=articleElement.addElement("author");

 

 

 

 

 

 

     //author元素中添加firstname,lastname元素,并用setText()設(shè)置他們的文本

 

 

 

 

 

 

     Element  firstNameElement=authorElement.addElement("firstname");

 

 

 

 

 

 

     firstNameElement.setText("Marcello");

 

 

 

 

 

 

     Element lastNameElement=authorElement.addElement("lastname");

 

 

 

 

 

 

     lastNameElement.setText("Vitaletti");

 

 

 

 

 

 

    

 

 

 

 

 

 

     return document;

 

 

 

 

 

 

     //使用addDocType() 方法添加文檔類型說明

 

 

 

 

 

 

     //document.addDocType("catalog",null,"file://c:/Dtds/catalog.dtd");

 

 

 

 

 

 

    /**try

 

 

 

 

 

 

       {

 

 

 

 

 

 

        XMLWriter output = new XMLWriter(

 

 

 

 

 

 

            new FileWriter( new File("mycatalog.xml") ));

 

 

 

 

 

 

        output.write( document );

 

 

 

 

 

 

        output.close();

 

 

 

 

 

 

        }

 

 

 

 

 

 

     catch(IOException e)

 

 

 

 

 

 

     {System.out.println(e.getMessage());}**/

 

 

 

 

 

 

}

 

 

 

 

 

 

 

 

/**

 

 

 

 

 

 * 格式化XML文檔,并按指定字符集輸出

 

 

 

 

 

 

 * @param document

 

 

 

 

 

 

 * @param fileName

 

 

 

 

 

 

* @param encoding  編碼格式

 

 

 

 

 

 

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

 

 

 

 

 

 

 */

 

 

 

 

 

 

public static int saveXml(Document document,

 

 

 

 

 

 

                                             String fileName,

 

 

 

 

 

 

                                             String encoding)

 

 

 

 

 

 

                                             throws UnsupportedEncodingException,

 

 

 

 

 

 

                                                     FileNotFoundException,

 

 

 

 

 

 

                                                     IOException{

 

 

 

 

 

 

      int returnValue = 0;

 

 

 

 

 

 

 

 

 

 

 

 

    XMLWriter output = null;

 

 

 

 

 

 

    /** 格式化輸出,類型IE瀏覽一樣*/

 

 

 

 

 

 

    OutputFormat format = OutputFormat.createPrettyPrint();

 

    /** 指定XML字符集編碼*/

 

 

 

 

 

 

    format.setEncoding(encoding);

 

 

 

 

 

 

   

 

 

 

 

 

 

    output = new XMLWriter(new FileOutputStream(new File(fileName)), format);

 

 

 

 

 

 

    output.write(document);

 

 

 

 

 

 

    output.close();       

 

 

 

 

 

 

 

 

 

 

 

 

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

 

 

 

 

 

 

    returnValue = 1;   

 

 

 

 

 

 

          

 

 

 

 

 

 

      return returnValue;

 

 

 

 

 

 

}

 

/**

 

 

 

 

 

 

 * 修改XML文檔,并按指定字符集輸出

 

 

 

 

 

 

 * @param inputXml

 

 

 

 

 

 

 * @param modified_filename 修改后的文件名(含絕對路徑)

 

 

 

 

 

 

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

 

 

 

 

 

 

 */

 

 

 

 

 

 

 

 public int modifyDocument(File inputXml,String modified_filename)
   int returnValue = 0;

 

 

 

 

 

 

try{

 

 

 

 

 

 

   SAXReader saxReader = new SAXReader();

 

 

 

 

 

 

   Document document = saxReader.read(inputXml);

 

 

 

 

 

 

 

 

 

 

 

 

//根據(jù)XPath語法查詢結(jié)點(diǎn)catalog下的journal下的articlelevel屬性

 

 

 

 

 

 

   List list = document.selectNodes("/catalog/journal/article/@level" );

 

 

 

 

 

 

   Iterator iter=list.iterator();

 

 

 

 

 

 

   while(iter.hasNext()){

 

 

 

 

 

 

    Attribute attribute=(Attribute)iter.next();

 

 

 

 

 

 

    if(attribute.getValue().equals("Intermediate")) //如果屬性值是Intermediate

 

 

 

 

 

 

      attribute.setValue("Introductory");

 

 

 

 

 

 

 

 

 

 

 

 

       }

 

 

 

 

 

 

  

 

 

 

 

 

 

   list = document.selectNodes("http://article/@date" );

 

 

 

 

 

 

   iter=list.iterator();

 

 

 

 

 

 

   while(iter.hasNext()){

 

 

 

 

 

 

    Attribute attribute=(Attribute)iter.next();

 

 

 

 

 

 

    if(attribute.getValue().equals("December-2001"))

 

 

 

 

 

 

      attribute.setValue("October-2002");

 

 

 

 

 

 

       }

 

 

 

 

 

 

  

 

 

 

 

 

 

    list = document.selectNodes("http://article" );

 

 

 

 

 

 

    iter=list.iterator();

 

 

 

 

 

 

    while(iter.hasNext()){

 

 

 

 

 

 

     Element element=(Element)iter.next();

 

 

 

 

 

 

     Iterator iterator=element.elementIterator("title");

 

 

 

 

 

 

      while(iterator.hasNext()){

 

 

 

 

 

 

        Element titleElement=(Element)iterator.next();

 

 

 

 

 

 

        if(titleElement.getText().equals("Java configuration with XML Schema"))

 

 

 

 

 

 

        titleElement.setText("Create flexible and extensible XML schema");                           }

 

 

 

 

 

 

             }

 

 

 

 

 

 

 

 

 

 

 

 

    list = document.selectNodes("http://article/author" );

 

 

 

 

 

 

    iter=list.iterator();

 

 

 

 

 

 

     while(iter.hasNext()){

 

 

 

 

 

 

     Element element=(Element)iter.next();

 

 

 

 

 

 

     Iterator iterator=element.elementIterator("firstname");

 

 

 

 

 

 

     while(iterator.hasNext()){

 

 

 

 

 

 

      Element firstNameElement=(Element)iterator.next();

 

 

 

 

 

 

      if(firstNameElement.getText().equals("Marcello"))

 

 

 

 

 

 

      firstNameElement.setText("Ayesha");

 

 

 

 

 

 

                                     }

 

 

 

 

 

 

                              }

 

 

 

 

 

 

 

 

 

 

 

 

    list = document.selectNodes("http://article/author" );

 

 

 

 

 

 

    iter=list.iterator();

 

 

 

 

 

 

     while(iter.hasNext()){

 

 

 

 

 

 

      Element element=(Element)iter.next();

 

 

 

 

 

 

      Iterator iterator=element.elementIterator("lastname");

 

 

 

 

 

 

     while(iterator.hasNext()){

 

 

 

 

 

 

      Element lastNameElement=(Element)iterator.next();

 

 

 

 

 

 

      if(lastNameElement.getText().equals("Vitaletti"))

 

 

 

 

 

 

      lastNameElement.setText("Malik");

 

 

 

 

 

 

 

 

 

 

 

 

                                  }

 

 

 

 

 

 

 

 

 

 

 

 

                               }

 

 

 

 

 

 

     XMLWriter output = new XMLWriter(

 

 

 

 

 

 

      new FileWriter( new File(modified_filename) ));

 

 

 

 

 

 

     output.write( document );

 

 

 

 

 

 

     output.close();

 

 

 

 

 

 

   }

 

 

 

 

 

 

 

 

 

 

 

 

  catch(DocumentException e)

 

 

 

 

 

 

                 {

 

 

 

 

 

 

                  System.out.println(e.getMessage());

 

 

 

 

 

 

                            }

 

 

 

 

 

 

 

 

 

 

 

 

  catch(IOException e){

 

 

 

 

 

 

                       System.out.println(e.getMessage());

 

 

 

 

 

 

                    }

 

 

 

 

 

 

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

 

 

 

 

 

 

    returnValue = 1;   

 

 

 

 

 

 

          

 

 

 

 

 

 

      return returnValue;

 

 

 

 

 

 

 

 

 

 

 

 

 }

 

 

 

 

 

 

 

 

 

 

 

 

public static void main(String[] argv)

 

 

 

 

 

 

{

 

 

 

 

 

 

   Rt savedomtoxml=new Rt();

 

 

 

 

 

 

   Document doc=savedomtoxml.generateDocument();

 

 

 

 

 

 

   try{

 

 

 

 

 

 

   int re=savedomtoxml.saveXml(doc,"savexml.xml","gb2312");  //生成的xml文件默認(rèn)狀態(tài)和類文件在同一個(gè)目錄下

 

 

 

 

 

 

   System.out.println(re);

 

 

 

 

 

 

   }

 

 

 

 

 

 

   catch(IOException e)

 

 

 

 

 

 

     {System.out.println(e.getMessage());}

 

 

 

 

 

 

  

 

 

 

 

 

 

   try{

 

 

 

 

 

 

   int modifyre=savedomtoxml.modifyDocument(new File("H:/dom4j/rt/orginal.xml"));

 

 

 

 

 

 

   System.out.println(modifyre);

 

 

 

 

 

 

   }

 

 

 

 

 

 

   catch(Exception e)

 

 

 

 

 

 

     {System.out.println(e.getMessage());}

 

 

 

 

 

 

  

 

 

 

 

 

 

}

 

 

 

 

 

 

 

 

 

 

 

 

}