XML 解析
1)DOM
2)SAX
DOM解析器把 XML文檔轉化爲一個包含其內容的樹,並可以對樹進行遍歷。用DOM解析模型的優點是編程容易,開發人員只需要調用建樹的指令,然後利用 navigation APIs訪問所需的樹節點來完成任務。可以很容易的添加和修改樹中的元素。然而由於使用DOM解析器的時候需要處理整個XML文檔,所以對性能和內存的要 求比較高,尤其是遇到很大的XML文件的時候。由於它的遍歷能力,DOM解析器常用於XML文檔需要頻繁的改變的服務中。
SAX解析器 採用了基於事件的模型,它在解析XML文檔的時候可以觸發一系列的事件,當發現給定的tag的時候,它可以激活一個回調方法,告訴該方法制定的標籤已經找 到。SAX對內存的要求通常會比較低,因爲它讓開發人員自己來決定所要處理的tag。特別是當開發人員只需要處理文檔中所包含的部分數據時,SAX這種擴 展能力得到了更好的體現。但用SAX解析器的時候編碼工作 會比較困難,而且很難同時訪問同一個文檔中的多處不同數據。
通俗點講,Dom 解析器是將xml文檔整個讀入內存中以便查找,而SAX解析器只是依次解析讀到的tag數據,當找到想要的數據時便可停止解析,不用讀取整個XML文檔至 內存。有很多開源項目提供了各種用於解析xml的包,其原因無非是在dom和sax的原理基礎上做一些優化工作。Java 中比較常用的操作xml的開源包 有 dom4j、JDOM、Crimson、Commons-Digester等等。。(後兩者均爲apache開源包)。
當然JAVA 裏也自帶了一些包用於解析、保存xml:javax.xml包、org.w3c.dom、org.xml.sax,更多具體的操作方法可以查看java api文檔(這幾個包都是內置的,官方API文檔裏就其詳盡的包描述)
這裏我們使用javax.xml,org.w3c.dom,給出如 何創建Dom樹、如何從.xml文件中生成Dom樹,如何將Dom樹保存到xml文件中。
生成一個Document空的文檔對象:
org.w3c.dom.Document doc = javax.xml.parsers.DocumentBuilderFactory.newInstance().
newDocumentBuilder().newDocument();
可 以這樣理解和記憶:要建立一個Document對象(這是一個產品),那麼先要有一個工廠DocumentBuilderFactory,由工廠“招聘 “一個製造者DocumentBuilder,然後由製造者來生產Document對象。
工廠DocumentBuilderFactory沒有 公有的構造方法,只能用newInstance()取得一個工廠。同樣DocumentBuilder也沒有公共構造方法。這裏涉及到設計模式裏的“工廠 方法模式”和“單態模式”,這樣做的意義我們以後將在“設計模式”一塊給出。
從.xml文件中生成Document對象:
javax.xml.parsers.DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new File(“fileName”));
其中parse方法可以是多種參數,可參看java api文檔。
取得根結點:
doc.getDocumentElement().childNodes().item(0);
可 以看到對dom樹操作就類似於在javascript裏用dom api操作xml了,事實上,兩者都是有w3c標準化組織提供的。
文件 存放xml Document對象。
javax.xml.transform.Transformer tf =
javax.xml.transform.TransformerFactory.newInstance().newTransformer();
tf.transform(new javax.xml.transform.dom.DOMSource(doc),
new javax.xml.transform.stream.StreamResult(new FileOutputStream(fileName)));
下面是一些簡單的包裝過的方法:
/**
*將dom樹對象 doc存入fileName提定的文件中
**/
public void saveToFile(Document doc, String fileName) throws TransformerFactoryConfigurationError, FileNotFoundException, TransformerException{
javax.xml.transform.Transformer trans = javax.xml.transform.TransformerFactory.newInstance().newTransformer();
trans.transform(new javax.xml.transform.dom.DOMSource(doc),
new javax.xml.transform.stream.StreamResult(new FileOutputStream(fileName)));
}
/**
*生成一個帶根結點名爲 rootName的Dom樹對象。
**/
public Document createXMLDoc(String rootName) throws FileNotFoundException, SAXException, IOException, ParserConfigurationException{
Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
doc.appendChild(doc.createElement(rootName));
return doc;
}
/**
*由給定文件名的xml文件生成一個Dom 樹。
*/
public Document createXMLFromFile(String fileName) throws SAXException, IOException,
ParserConfigurationException {
File xmlFile = new File(fileName);
if (!xmlFile.exists()) {
System.err.println("File " + fileName + "doesn't exist!");
System.exit(0);
}
return DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(
fileName);
}