天天看點

Java操作XML檔案 dom4j 篇

在項目中,我們很多都用到了xml檔案,無論是參數配置還是與其它系統的資料互動。

今天就來講一下Java 中使用dom4j來操作XML檔案。

我們需要引入的包:

//檔案包 

import java.io.ByteArrayOutputStream; 

import java.io.File; 

import java.io.FileWriter; 

//工具包 

import java.util.Iterator; 

import java.util.List; 

//dom4j包 

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;

1、将XML檔案的内容轉化為String

   /** 

    * doc2String 

    * 将xml文檔内容轉為String 

    * @return 字元串 

    * @param document 

    */ 

   public static String doc2String(Document document) 

   { 

      String s = ""; 

      try 

      { 

           //使用輸出流來進行轉化 

           ByteArrayOutputStream out = new ByteArrayOutputStream(); 

           //使用GB2312編碼 

           OutputFormat format = new OutputFormat("  ", true, "GB2312"); 

           XMLWriter writer = new XMLWriter(out, format); 

           writer.write(document); 

           s = out.toString("GB2312"); 

      }catch(Exception ex) 

      {             

           ex.printStackTrace(); 

      }       

      return s; 

   }

2、将符合XML格式的String 轉化為XML Document

    * string2Document 

    * 将字元串轉為Document 

    * @return  

    * @param s xml格式的字元串 

   public static Document string2Document(String s) 

      Document doc = null; 

           doc = DocumentHelper.parseText(s); 

      } 

      return doc; 

3、将Document對象儲存為一個xml檔案到本地

    * doc2XmlFile 

    * 将Document對象儲存為一個xml檔案到本地 

    * @return true:儲存成功  flase:失敗 

    * @param filename 儲存的檔案名 

    * @param document 需要儲存的document對象 

   public static boolean doc2XmlFile(Document document,String filename) 

      boolean flag = true; 

            /* 将document中的内容寫入檔案中 */ 

            //預設為UTF-8格式,指定為"GB2312" 

            OutputFormat format = OutputFormat.createPrettyPrint(); 

            format.setEncoding("GB2312"); 

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

            writer.write(document); 

            writer.close();             

        }catch(Exception ex) 

        { 

            flag = false; 

            ex.printStackTrace(); 

        } 

        return flag;       

4、将xml格式的字元串儲存為本地檔案,如果字元串格式不符合xml規則,則傳回失敗

    * string2XmlFile 

    * 将xml格式的字元串儲存為本地檔案,如果字元串格式不符合xml規則,則傳回失敗 

    * @param str 需要儲存的字元串 

   public static boolean string2XmlFile(String str,String filename) 

         Document doc =  DocumentHelper.parseText(str);        

         flag = doc2XmlFile(doc,filename); 

      }catch (Exception ex) 

         flag = false; 

         ex.printStackTrace(); 

      return flag; 

5、載入一個xml文檔

    * load 

    * 載入一個xml文檔 

    * @return 成功傳回Document對象,失敗傳回null 

    * @param uri 檔案路徑 

   public static Document load(String filename) 

      Document document = null; 

      try  

      {  

          SAXReader saxReader = new SAXReader(); 

          document = saxReader.read(new File(filename));            filename = "E://11.txt"

      catch (Exception ex){ 

          ex.printStackTrace(); 

      }   

      return document; 

 6、示範String儲存為xml檔案

    * xmlWriteDemoByString 

    * 示範String儲存為xml檔案 

   public void xmlWriteDemoByString() 

      /** xml格式标題 "<?xml version='1.0' encoding='GB2312'?>" 可以不用寫*/ 

      s = "<config>\r\n" 

         +"   <ftp name='DongDian'>\r\n" 

         +"     <ftp-host>127.0.0.1</ftp-host>\r\n" 

         +"     <ftp-port>21</ftp-port>\r\n" 

         +"     <ftp-user>cxl</ftp-user>\r\n" 

         +"     <ftp-pwd>longshine</ftp-pwd>\r\n" 

         +"     <!-- ftp最多嘗試連接配接次數 -->\r\n" 

         +"     <ftp-try>50</ftp-try>\r\n" 

         +"     <!-- ftp嘗試連接配接延遲時間 -->\r\n" 

         +"     <ftp-delay>10</ftp-delay>\r\n" 

         +"  </ftp>\r\n" 

         +"</config>\r\n"; 

      //将檔案生成到classes檔案夾所在的目錄裡    

      string2XmlFile(s,"xmlWriteDemoByString.xml");    

      //将檔案生成到classes檔案夾裡    

      string2XmlFile(s,"classes/xmlWriteDemoByString.xml");   

7、示範手動建立一個Document,并儲存為XML檔案

    * 示範手動建立一個Document,并儲存為XML檔案 

   public void xmlWriteDemoByDocument() 

        /** 建立document對象 */ 

        Document document = DocumentHelper.createDocument(); 

        /** 建立config根節點 */ 

        Element configElement = document.addElement("config"); 

        /** 建立ftp節點 */ 

        configElement.addComment("東電ftp配置"); 

        Element ftpElement = configElement.addElement("ftp"); 

        ftpElement.addAttribute("name","DongDian"); 

        /** ftp 屬性配置 */ 

        Element hostElement = ftpElement.addElement("ftp-host"); 

        hostElement.setText("127.0.0.1"); 

        (ftpElement.addElement("ftp-port")).setText("21"); 

        (ftpElement.addElement("ftp-user")).setText("cxl"); 

        (ftpElement.addElement("ftp-pwd")).setText("longshine"); 

        ftpElement.addComment("ftp最多嘗試連接配接次數"); 

        (ftpElement.addElement("ftp-try")).setText("50"); 

        ftpElement.addComment("ftp嘗試連接配接延遲時間"); 

        (ftpElement.addElement("ftp-delay")).setText("10");     

        /** 儲存Document */ 

        doc2XmlFile(document,"classes/xmlWriteDemoByDocument.xml"); 

8、示範讀取檔案的具體某個節點的值

    *  示範讀取檔案的具體某個節點的值  

   public static void xmlReadDemo() 

      Document doc = load("classes/xmlWriteDemoByDocument.xml"); 

      //Element root = doc.getRootElement(); 

      /** 先用xpath查找所有ftp節點 并輸出它的name屬性值*/ 

      List list = doc.selectNodes("/config/ftp" ); 

      Iterator it = list.iterator(); 

      while(it.hasNext()) 

      {    

          Element ftpElement = (Element)it.next(); 

          System.out.println("ftp_name="+ftpElement.attribute("name").getValue()); 

      /** 直接用屬性path取得name值 */ 

      list = doc.selectNodes("/config/ftp/@name" ); 

      it = list.iterator(); 

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

          System.out.println("@name="+attribute.getValue()); 

      /** 直接取得DongDian ftp的 ftp-host 的值 */ 

      list = doc.selectNodes("/config/ftp/ftp-host" ); 

      Element hostElement=(Element)it.next(); 

      System.out.println("DongDian's ftp_host="+hostElement.getText()); 

9、修改或删除某個值或屬性

/** ftp節點删除ftp-host節點 */ 

ftpElement.remove(hostElement);  

/** ftp節點删除name屬性 */ 

ftpElement.remove(nameAttribute); 

/** 修改ftp-host的值 */ 

hostElement.setText("192.168.0.1");  

/** 修改ftp節點name屬性的值 */ 

nameAttribute.setValue("ChiFeng");

dom4j(Version 1.6.1)快速入門

Parsing XML

    或許你想要做的第一件事情就是解析一個某種類型的XML文檔,用dom4j很容易做到。請看下面的示範代碼:

import java.net.URL;

import org.dom4j.Document;

import org.dom4j.DocumentException;

import org.dom4j.io.SAXReader;

public class Foo {

    public Document parse(URL url) throws DocumentException {

        SAXReader reader = new SAXReader();

        Document document = reader.read(url);

        return document;

    }

}

使用疊代器(Iterators)

    我們可以通過多種方法來操作XML文檔,這些方法傳回java裡标準的疊代器(Iterators)。例如:

public void bar(Document document) throws DocumentException {

        Element root = document.getRootElement();

        //疊代根元素下面的所有子元素

        for ( Iterator i = root.elementIterator(); i.hasNext(); ) {

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

            //處理代碼

        }

        //疊代根元素下面名稱為"foo"的子元素

        for ( Iterator i = root.elementIterator( "foo" ); i.hasNext(); ) {

            Element foo = (Element) i.next();

        // 疊代根元素的屬性attributes)元素

        for ( Iterator i = root.attributeIterator(); i.hasNext(); ) {

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

            // do something

     }

強大的XPath導航

    在dom4j中XPath可以表示出在XML樹狀結構中的Document或者任意的節點(Node)(例如:Attribute,Element 或者ProcessingInstruction等)。它可以使在文檔中複雜的操作僅通過一行代碼就可以完成。例如:

public void bar(Document document) {

        List list = document.selectNodes( "//foo/bar" );

        Node node = document.selectSingleNode( "//foo/bar/author" );

        String name = node.valueOf( "@name" );

    如果你想得到一個XHTML文檔中的所有超文本連結(hypertext links)你可以使用下面的代碼:

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

    如果你需要關于XPath語言的任何幫助,我們強烈推薦這個站點

Zvon tutorial

他會通過一個一個的例子引導你學習。

快速周遊(Fast Looping)

如果你不得不周遊一個非常大的XML文檔,然後才去執行,我們建議你使用快速周遊方法(fast looping method),它可以避免為每一個循環的節點建立一個疊代器對象,如下所示:

public void treeWalk(Document document) {

        treeWalk( document.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....

生成一個新的XML文檔對象

    在dom4j中你可能常常希望用程式生成一個XML文檔對象,下面的程式為你進行了示範:

import org.dom4j.DocumentHelper;

import org.dom4j.Element;

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

        Element author2 = root.addElement( "author" )

            .addAttribute( "name", "Bob" )

            .addAttribute( "location", "US" )

            .addText( "Bob McWhirter" );

将一個文檔對象寫入檔案中

    将一個文檔對象寫入Writer對象的一個簡單快速的途徑是通過write()方法。

        FileWriter out = new FileWriter( "foo.xml" );

        document.write( out );

如果你想改變輸出檔案的排版格式,比如你想要一個漂亮的格式或者是一個緊湊的格式,或者你想用Writer 對象或者OutputStream 對象來操作,那麼你可以使用XMLWriter 類。

import org.dom4j.io.OutputFormat;

    public void write(Document document) throws IOException {

        // 寫入檔案

        XMLWriter writer = new XMLWriter(

            new FileWriter( "output.xml" )

        );

        writer.write( document );

        writer.close();

        // 以一種優雅的格式寫入System.out對象

        OutputFormat format = OutputFormat.createPrettyPrint();

        writer = new XMLWriter( System.out, format );

        // 以一種緊湊的格式寫入System.out對象

        format = OutputFormat.createCompactFormat();

轉化為字元串,或者從字元串轉化

    如果你有一個文檔(Document)對象或者任何一個節點(Node)對象的引用(reference),象屬性(Attribute)或者元素(Element),你可以通過asXML()方法把它轉化為一個預設的XML字元串:

        Document document = ...;

        String text = document.asXML();

如果你有一些XML内容的字元串表示,你可以通過DocumentHelper.parseText()方法将它重新轉化為文檔(Document)對象:

        String text = "<person> <name>James</name> </person>";

        Document document = DocumentHelper.parseText(text);

通過XSLT樣式化文檔(Document)

    使用Sun公司提供的

JAXP

 API将XSLT 應用到文檔(Document)上是很簡單的。它允許你使用任何的XSLT引擎(例如:Xalan或SAXON等)來開發。下面是一個使用JAXP建立一個轉化器(transformer),然後将它應用到文檔(Document)上的例子:

import javax.xml.transform.Transformer;

import javax.xml.transform.TransformerFactory;

import org.dom4j.io.DocumentResult;

import org.dom4j.io.DocumentSource;

    public Document styleDocument(

        Document document, 

        String stylesheet

    ) throws Exception {

        // 使用 JAXP 加載轉化器

        TransformerFactory factory = TransformerFactory.newInstance();

        Transformer transformer = factory.newTransformer( 

            new StreamSource( stylesheet ) 

        // 現在來樣式化一個文檔(Document)

        DocumentSource source = new DocumentSource( document );

        DocumentResult result = new DocumentResult();

        transformer.transform( source, result );

        // 傳回經過樣式化的文檔(Document)

        Document transformedDoc = result.getDocument();

        return transformedDoc;

閱讀(965