解析XML文件

總結兩種解析包解析XML文件

Jaxp(sun,j2se)、dom4j(dom4j)

一.JAXP解析XML文件

   JAXP 開發包是J2SE的一部分,它由javax.xml、org.w3c.dom 、org.xml.sax 包及其子包組成

1)使用JAXP進行DOM解析
   javax.xml.parsers 包中的DocumentBuilderFactory用於創建DOM模式的解析器對象 , DocumentBuilderFactory是一個抽象工廠類,它不能直接實例化,但該類提供了一個 newInstance方法 ,這個方法會根據本地平臺默認安裝的解析器,自動創建一個工廠的對象並返回。

解析步驟:

 1:調用 DocumentBuilderFactory.newInstance() 方法得到創建 DOM 解析器的工廠。
    DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();

 2:調用工廠對象的 newDocumentBuilder方法得到 DOM 解析器對象。
    DocumentBuilder builder = builderFactory.newDocumentBuilder();

 3:調用 DOM 解析器對象的 parse() 方法解析 XML 文檔,得到代表整個文檔的 Document 對象,進行可以利用DOM特性對整個XML文檔進行操作了。
    Document doc = builder.parse(new File("book.xml"));

DOM模型(document object model)
    DOM解析器在解析XML文檔時,會把文檔中的所有元素,按照其出現的層次關係,解析成一個個Node對象(節點),並以樹的結構組織起來,存儲到內存中。
   JAXP中的文檔對象:
      Document:文檔
      Element:元素
      Attr:屬性
     CharacterData:標籤體

對文檔樹的增刪該查只是對內存中的對象進行的操作,如果希望將修改對xml文件起作用,就需要進行XML文檔更新

更新XML文件步驟:

javax.xml.transform包中的Transformer類用於把代表XML文件的Document對象轉換爲某種格式後進行輸出
  1: 獲取Transformer工廠    
        TransformerFactory transformerFactory  =TransformerFactory.newInstance();
  2:獲取Transfomer對象
        Transformer transformer =  transformerFactory.newTransformer();

  3:設置輸出屬性的編碼

      transformer.setOutputProperty(OutputKeys.ENCODING,"gb2312");

  4:創建代表輸入和輸出的Source和Result對象
        Source source = new DOMSource(doc);
        Result result = new StreamResult(new FIle("book.xml"));
使用Transformer將 XMLSource 轉換爲 Result
        transformer.transform(source , Result);


2)使用JAXP進行SAX解析

   SAX採用事件處理的方式解析XML文件,利用 SAX 解析 XML 文檔,涉及兩個部分:解析器和事件處理器。

   SAX每當解析到XML文檔的一個組成部分,都會去調用事件處理器的一個方法,解析器在調用事件處理器的方法時,會把當前解析到的xml文件內容作爲方法的參數傳遞給事件處理器。事件處理器由程序員編寫,程序員通過事件處理器中方法的參數,就可以很輕鬆地得到sax解析器解析到的數據,從而可以決定如何對數據進行處理。

閱讀ContentHandler API文檔,常用方法:startElement、endElement、characters。

SAX解析XML文件的步驟:

    1:使用SAXParserFactory創建SAX解析工廠
       SAXParserFactory spf = SAXParserFactory.newInstance();
    2:通過SAX解析工廠得到解析器對象        
       SAXParser sp = spf.newSAXParser();

    3:通過解析器對象得到一個XML的讀取器
       XMLReader xmlReader = sp.getXMLReader();

    4:設置讀取器的事件處理器
        xmlReader.setContentHandler(new MyContentHandler());

    5:解析xml文件    
        xmlReader.parse("book.xml");


ContentHandler:

void setContentHandler(ContentHandler handler)
ContentHandler是一個接口,我們可以自己寫一個類實現這個接口,其中提供瞭如下重要的方法:
 void characters(char[] ch, int start, int length)
  接收字符數據的通知。
endDocument()
接收文檔的結尾的通知。
startDocument()
接收文檔的開始的通知。
startElement(String uri, String localName, String qName, Attributes atts)
接收元素開始的通知。
void endElement(String uri, String localName, String qName)
接收元素結束的通知。

DefaultHandler是一個類,他默認實現了ContentHandler接口,並提供了其中所有方法的空實現,我們可以自己寫一個類繼承這個類,複寫其中我們需要使用到的方法即可


DOM4J解析XML

Dom4j是一個簡單、靈活的開放源代碼的庫。Dom4j是由早期開發JDOM的人分離出來而後獨立開發的。與JDOM不同的是,dom4j使用接口和抽象基類,雖然Dom4j的API相對要複雜一些,但它提供了比JDOM更好的靈活性。 Dom4j是一個非常優秀的Java XML API,具有性能優異、功能強大和極易使    用的特點。現在很多軟件採用的Dom4j

使用Dom4j開發,需下載dom4j相應的jar文件

DOM4J解析XML的步驟:

  1:創建解析器:
        SAXReader reader = new SAXReader();
  2:利用解析器讀入xml文檔:

        Document   document = reader.read(new File("input.xml"));
  3:獲取文檔的根節點:
        Element root = document.getRootElement();


更新XML文件

方式一:

調用Node提供的write(Writer writer) 方法,使用默認方式將節點輸出到流中:
        node.write(new FileWriter("book.xml"));

亂碼問題:Dom4j在將文檔載入內存時使用的是文檔聲明中encoding屬性聲明的編碼集進行編碼,如果在此時使用的writer的內部編碼集與最初載入內存時使用的編碼集不同則會出現亂碼問題。FileWriter默認使用操作系統本地碼錶即gb2312編碼,並且無法更改。此時可以使用OutputStreamWriter(FileOutputStream("filePath"),"utf-8");的方式自己封裝一個指定碼錶的Writer使用,從而解決亂碼問題。


方式二:

利用XMLWriter寫出Node:

    XMLWriter writer = new XMLWriter(new  FileWriter("output.xml"));

    writer.write(node);

    writer.close();
注意:使用這種方式輸出時,XMLWriter首先會將內存中的docuemnt翻譯成UTF-8格式的document,在進行輸出,這時有可能出現亂碼問題。
可以使用OutputFormat 指定XMLWriter轉換的編碼爲其他編碼。
    OutputFormat format = OutputFormat.createPrettyPrint();            
    format.setEncoding("GBK");     

    XMLWriter writer = new XMLWriter(newFileWriter("output.xml"),format);
Writer使用的編碼集與文檔載入內存時使用的編碼集不同導致亂碼,使用字節流或自己封裝指定編碼的字符流即可。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章