千里馬

          天馬行空

          Dom4j的使用(Dom4j對xml的解析即增刪改查)

                dom4j是一個Java的XML API,類似于jdom,用來讀寫XML文件的。dom4j是一個非常非常優秀的Java XML API,具有性能優異、功能強大和極端易用使用的特點,同時它也是一個開放源代碼的軟件,可以在SourceForge上找到它。在IBM developerWorks上面可以找到一篇文章,對主流的Java XML API進行的性能、功能和易用性的評測,dom4j無論在那個方面都是非常出色的。如今你可以看到越來越多的Java軟件都在使用dom4j來讀寫XML,特別值得一提的是連Sun的JAXM也在用dom4j。這是必須使用的jar包, Hibernate用它來讀寫配置文件。

                 在國內比較流行的是使用JDOM作為解析器,兩者各擅其長,但DOM4J最大的特色是使用大量的接口,這也是它被認為比JDOM靈活的主要原因。大師不是說過么,“面向接口編程”。目前使用DOM4J的已經越來越多。如果你善于使用JDOM,不妨繼續用下去,只看看本篇文章作為了解與比較,如果你正要采用一種解析器,不如就用DOM4J吧。

          Attribute定義了XML的屬性
          Branch為能夠包含子節點的節點如XML元素(Element)和文檔(Docuemnts)定義了一個公共的行為,
          CDATA 定義了XML CDATA 區域
          CharacterData是一個標識借口,標識基于字符的節點。如CDATA,Comment, Text.
          Comment 定義了XML注釋的行為
          定義了XML文檔
          DocumentType 定義XML DOCTYPE聲明
          Element定義XML 元素
          ElementHandler定義了 Element 對象的處理器
          被 ElementHandler 使用,用于取得當前正在處理的路徑層次信息
          Entity定義 XML entity
          Node為所有的dom4j中XML節點定義了多態行為
          NodeFilter 定義了在dom4j節點中產生的一個濾鏡或謂詞的行為(predicate)
          ProcessingInstruction 定義 XML 處理指令.
          Text 定義XML 文本節點.
          Visitor 用于實現Visitor模式.
          XPath 在分析一個字符串后會提供一個XPath 表達式
          要想弄懂這套接口,關鍵的是要明白接口的繼承關系:
          一目了然,很多事情都清楚了。大部分都是由Node繼承來的。知道這些關系,將來寫程序就不會出現ClassCastException了。
          下面給出一些例子(部分摘自DOM4J自帶的文檔),簡單說一下如何使用。

          一、 讀取并解析XML文檔:



              // 從文件讀取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對象就帶表了整個XML。
          讀取的字符編碼是按照XML文件頭定義的編碼來轉換。如果遇到亂碼問題,注意要把各處的編碼名稱保持一致即可。
          二、取得Root節點
          讀取后的第二步,就是得到Root節點。熟悉XML的人都知道,一切XML分析都是從Root元素開始的。

             public Element getRootElement(Document doc){
                 return doc.getRootElement();
              }

          三、 遍歷XML樹(三種方法)

          1)枚舉:


              // 枚舉所有子節點
              for ( Iterator i = root.elementIterator(); i.hasNext(); ) {
                 Element element = (Element) i.next();
                 // do something
              }
              // 枚舉名稱為foo的節點
              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)遞歸





              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....
                     }
                 }
          }


          3)Visitor模式


                  public class MyVisitor extends VisitorSupport {
                     public void visit(Element element){
                         System.out.println(element.getName());
                     }
                     public void visit(Attribute attr){
                         System.out.println(attr.getName());
                     }
                  }

                  調用:  root.accept(new MyVisitor())
             Visitor接口提供多種Visit()的重載,根據XML不同的對象,將采用不同的方式來訪問。上面是給出的Element和Attribute的簡單實現,一般比較常用的就是這兩個。VisitorSupport是DOM4J提供的默認適配器,Visitor接口的Default Adapter模式,這個模式給出了各種visit(*)的空實現,以便簡化代碼。

              注意,這個Visitor是自動遍歷所有子節點的。如果是root.accept(MyVisitor),將遍歷子節點。 

          五、 字符串與XML的轉換

          有時候經常要用到字符串轉換為XML或反之,

              // XML轉字符串
            Document document = ...;
              String text = document.asXML();
          // 字符串轉XML
              String text =  James ;
              Document document = DocumentHelper.parseText(text);

          六、 用XSLT轉換XML

             public Document styleDocument(
                 Document document,
                 String stylesheet
              ) throws Exception {
              // load the transformer using JAXP
              TransformerFactory factory = TransformerFactory.newInstance();
              Transformer transformer = factory.newTransformer(
                 new StreamSource( stylesheet )
              );
              // now lets style the given document
              DocumentSource source = new DocumentSource( document );
              DocumentResult result = new DocumentResult();
              transformer.transform( source, result );
              // return the transformed document
              Document transformedDoc = result.getDocument();
              return transformedDoc;
          }

          七、 創建XML
            一般創建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 Strachan);
                 Element author2 =
                     root
                        .addElement(author)
                        .addAttribute(name, Bob)
                        .addAttribute(location, US)
                        .addText(Bob McWhirter);
                 return document;
              }

          八、文件輸出
              一個簡單的輸出方法是將一個Document或任何的Node通過write方法輸出

              FileWriter out = new FileWriter( foo.xml );
              document.write(out);

            如果你想改變輸出的格式,比如美化輸出或縮減格式,可以用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 );
              }


          最后附上,我做測試一份簡單代碼:

          package com.test;

          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;

          public class XMLTest {
               /**
               * 建立一個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");
                 /** 格式化輸出,類型IE瀏覽一樣 */
                 OutputFormat format = OutputFormat.createPrettyPrint();
                 /** 指定XML編碼 */
                 format.setEncoding("GBK");
                 try{
                     /** 將document中的內容寫入文件中 */
                     XMLWriter writer = new XMLWriter(new FileWriter(new File(filename)),format);
                     writer.write(document);
                     writer.close();
                     /** 執行成功,需返回1 */
                     returnValue = 1;
                 }catch(Exception ex){
                     ex.printStackTrace();
                 }
                       
                 return returnValue;
              }
              /**
               * 修改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;
               }
              /**
               * 格式化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("UTF-8");
                     writer= new XMLWriter(new FileWriter(new File(filename)),format);
                     writer.write(document);
                     writer.close();     
                     /** 執行成功,需返回1 */
                     returnValue = 1;    
                 }catch(Exception ex){
                     ex.printStackTrace();
                 }
                 return returnValue;
              }
              public static void main(String[] args) {
                XMLTest xmlTest=    new XMLTest();
                System.out.println(xmlTest.createXMLFile("holen.xml"));
          //      System.out.println(xmlTest.ModiXMLFile("holen.xml", "newholen.xml"));
          //      System.out.println(xmlTest.formatXMLFile("holen.xml"));
              }
          }

          posted on 2013-12-25 13:47 Mr Lee 閱讀(4082) 評論(0)  編輯  收藏


          只有注冊用戶登錄后才能發表評論。


          網站導航:
           

          My Links

          Blog Stats

          常用鏈接

          留言簿

          隨筆分類

          隨筆檔案

          文章檔案

          (hibernate)http://www.aygfsteel.com/dyllove98/archive/2012/05/12/377959.html

          搜索

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 隆尧县| 葵青区| 黎川县| 西丰县| 侯马市| 大冶市| 台东市| 上饶市| 大新县| 德庆县| 乌兰县| 凉城县| 喀喇沁旗| 绥化市| 弋阳县| 华安县| 高唐县| 安乡县| 巴中市| 宜宾县| 云和县| 长乐市| 朝阳区| 大竹县| 安丘市| 宝坻区| 渭源县| 钟祥市| 闻喜县| 浦北县| 长宁区| 博罗县| 西吉县| 龙岩市| 丽江市| 岳普湖县| 黑山县| 河源市| 三亚市| 巴塘县| 五华县|