XML

XML 技術是隨着 Java 的發展而發展起來的。在 XML 出現以前對於簡單的數據格式一般是存儲在 ini 配置文件等文本文件中,複雜的格式則採用自定義的文件格式,所以對於每種文件格式都要有專門的解析程序。 XML 出現之後解決了這個問題,程序面對的是有固定格式的 XML 文件,只要經過標準 API 就能夠進行 XML 文件的處理。
XML 文件在案例系統中應用是很普遍的,好比 ClientConfig.xml 、 ServerConfig.xml 文件就是使用 XML 文件來作配置文件的,元數據文件以及元數據加載器更是離不開 XML 。所以總結一下處理技術。java

    XML處理技術比較node

在 Java 領域 XML 文件的技術大體分爲兩類: XML API 和 OXMapping 。 XML API 是 XML 處理的基礎,可選技術包括 JDOM 、 Dom4j 等; OXMapping 是 Object-XML Mapping 的簡稱,這種技術隱藏了 XML 底層操做的細節,能夠將 XML 文件映射成一個 JavaBean 對象,也能夠把一個 JavaBean 對象保存成一個 XML 文件,可選技術 XStream 、 Digester 、 Castor 等。 XML API 和 OXMapping 的關係相似於 JDBC 和 ORMaping 的關係, OXMapping 內部實現使用 XML API 來完成,兩種實現技術從不一樣的層面實現了 XML 的處理。設計模式


XML API
此類 XML 處理技術中最流行的莫過於 JDOM 和 Dom4j 了,兩者的使用方式很是類似。不過 Dom4j 的優點比 JDOM 更明顯一些:
DOM4J是dom4j.org出品的一個開源XML解析包,它的網站中這樣定義:
Dom4j是一個易用的、開源的庫,用於XML,XPath和XSLT。它應用於Java平臺,採用了Java集合框架並徹底支持DOM,SAX和JAXP。
DOM4J使用起來很是簡單。只要你瞭解基本的XML-DOM模型,就能使用。
dom4j是sourceforge.net上的一個開源項目,主要用於對XML的解析。從2001年7月發佈初版以來,已陸續推出多個版本。
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異常,其餘的包能夠選擇用之。api

Dom4j 支持 XPath 等高級特性;
正是因爲這些優勢,不少開源項目都開始使用 Dom4j 作 XML 解析技術,本書也將使用 Dom4j 作爲 XML 處理的首選。
OXMapping
使用 XML API 解析是略顯煩瑣的,受 ORMapping 技術的啓發,人們發明了 OXMapping 技術,使用 OXMapping 技術,咱們能夠將 XML 文件映射成一個 JavaBean 對象,也能夠把一個 JavaBean 對象保存成一個 XML 文件,這大大簡化了咱們的開發工做量,使得開發人員能更多的關注應用層面的東西。app

開源世界中涌現出不少 OXMapping 框架,包括 XStream 、 Digester 、 Castor 等。 XStream 和 Digester 把映射的過程在代碼中完成,而 Castor 則須要寫一個和 Hibernate 中 cfg.xml 相似的映射配置文件。
與 Digester 比起來, XStream 的主要優勢就是更加小巧,使用也更加方便,不過目前使用 Digester 是「開源名牌」 Apache 下的子項目,網上能夠參考的資料也比 XStream 多,好在 XStream 比較簡潔,因此並不會對 XStream 形成太大影響。框架


============================================================================
1、利用dom4j解析xml
認識一下它的接口:dom

Attribute 
Attribute定義了XML的屬性工具

Branch 
Branch爲可以包含子節點的節點如XML元素(Element)和文檔(Docuemnts)定義了一個公共的行爲網站

CDATA 
CDATA 定義了XML CDATA 區域編碼

CharacterData 
CharacterData是一個標識藉口,標識基於字符的節點。如CDATA,Comment, Text.

Comment 
Comment 定義了XML註釋的行爲

Document 
定義了XML文檔

DocumentType 
DocumentType 定義XML DOCTYPE聲明

Element
Element定義XML 元素

ElementHandler 
ElementHandler定義了 Element 對象的處理器

ElementPath 
被 ElementHandler 使用,用於取得當前正在處理的路徑層次信息

Entity 
Entity定義 XML entity

Node 
Node爲全部的dom4j中XML節點定義了多態行爲

NodeFilter 
NodeFilter 定義了在dom4j節點中產生的一個濾鏡或謂詞的行爲(predicate)

ProcessingInstruction 
ProcessingInstruction 定義 XML 處理指令.

Text 
Text 定義XML 文本節點.

Visitor 
Visitor 用於實現Visitor模式.

XPath 
XPath 在分析一個字符串後會提供一個XPath 表達式
看名字大體就知道它們的涵義如何了。
================================================================
具體實現技術:

1.               讀取並解析XML文檔:
讀寫XML文檔主要依賴於org.dom4j.io包,其中提供DOMReader和SAXReader兩類不一樣方式,而調用方式是同樣的。這就是依靠接口的好處。

     從文件讀取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文件頭定義的編碼來轉換。若是遇到亂碼問題,注意要把各處的編碼名稱保持一致便可。

2.     取得Root節點
讀取後的第二步,就是獲得Root節點。熟悉XML的人都知道,一切XML分析都是從Root元素開始的。

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

3.     遍歷XML樹(暫時小結4種方法)

DOM4J提供至少3種遍歷節點的方法:
1)    迭代全部子節點  
     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();
     }

     迭代屬性
     for ( Iterator i = root.attributeIterator(); i.hasNext(); ) {
        Attribute attribute = (Attribute) i.next();      
     }
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....
            }
        }
}

3) Visitor模式(訪問者模式),很方變!
最使人興奮的是DOM4J對Visitor的支持,這樣能夠大大縮減代碼量,而且清楚易懂。瞭解設計模式的人都知道,Visitor是GOF設計模式之一。其主要原理就是兩種類互相保有對方的引用,而且一種做爲Visitor去訪問許多Visitable。咱們來看DOM4J中的Visitor模式(快速文檔中沒有提供)
只須要自定一個類實現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),將遍歷子節點。我第一次用的時候,認爲是須要本身遍歷,便在遞歸中調用Visitor,結果可想而知。

4). XPath支持,我比較喜歡用這個方法解析xml,目的性強,靈活!
     DOM4J對XPath有良好的支持,如訪問一個節點,可直接用XPath選擇。

    public void bar(Document document) {
                       注意:括號內路徑的寫法
        
         List list = document.selectNodes( //foo/bar );
         for(int i=0;i<list.size();i++){
         Element ee=(Element)list.get(i);
         String name=ee.getName();
         String value=ee.getText();
}
         Node node = document.selectSingleNode(//foo/bar/author);
         //Element elem = (Element)doc.selectSingleNode("//subA");
         String name = node.valueOf( @name );
      }

     例如,若是你想查找XHTML文檔中全部的超連接,下面的代碼能夠實現:

     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的轉換
有時候常常要用到字符串轉換爲XML或反之,

    XML轉字符串
  Document document = ...;
     String text = document.asXML();

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

6 、用XSLT轉換XML

    public Document styleDocument( Document document, String stylesheet ) throws Exception {
   
      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;
}

7. 建立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;
     }

8. 文件輸出
     一個簡單的輸出方法是將一個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 );
     }
這裏有兩點須要注意的:

( 1 ) OutputFormat format = OutputFormat.createPrettyPrint()

XML 一般是須要人閱讀的, Dom4j 默認的生成格式是緊縮格式的,這樣能夠減小空間佔用,可是帶來的缺點就是文件格式很是難看,所以咱們採用鎖緊格式進行輸出。

( 2 ) format.setEncoding("GB2312")

Dom4j 默認的編碼格式是「 UTF-8 」,這在輸出中文字符的時候會有問題,所以咱們改爲「 GB2312 」格式。

這裏使用了 Dom4j 提供的工具類 DocumentHelper 提供的 createElement 方法來建立一個節點,這個工具類還有 public static CDATA createCDATA(String text) 、 public static Comment createComment(String text) 、 public static Entity createEntity(String name, String text) 等方法能夠幫助咱們更快的建立節點。 DocumentHelper 還提供了 parseText 方法,能夠直接將字符串解析成 Documen 對象。九、修改節點、刪除節點(略,寫的太累拉)Element有幾個重要的方法:           addComment:添加註釋           addAttribute:添加屬性           addElement:添加子元素           addText:添加節點值           setText:修改節點值           setvalue:修改節點值           remove:刪除節點值

相關文章
相關標籤/搜索