解析xml有四種方法:DOM,SAX,DOM4j,JDOM. 我們主要學了兩種:DOM和SAX. DOM適于解析比較簡單的XML而SAX則適于解析較復雜的XML文件。各有各的好。 DOM和SAX的不同: 1. DOM是基于內存的,不管文件有多大,都會將所有的內容預先裝載到內存中。從而消耗很大的內存空間。而SAX是基于事件的。當某個事件被觸發時,才獲取相應的XML的部分數據,從而不管XML文件有多大,都只占用了少量的內存空間。 2. DOM可以讀取XML也可以向XML文件中插入數據,而SAX卻只能對XML進行讀取,而不能在文件中插入數據。這也是SAX的一個缺點。 3.SAX的另一個缺點:DOM我們可以指定要訪問的元素進行隨機訪問,而SAX則不行。SAX是從文檔開始執行遍歷的。并且只能遍歷一次。也就是說我們不能隨機的訪問XML文件,只能從頭到尾的將XML文件遍歷一次(當然也可以中間截斷遍歷)。 DOM和SAX對XML文件的解析: 1. 在使用DOM解析XML時,我們首先需要通過DocumentBuilderFactory這個類得到一個工廠的API,使應用程序能夠從XML文檔獲取 生成對象樹的解析器。通過此類的 newinstance() 方法我們可以獲得此類的一個新實例。然后通過創建DocumentBuilder的實例使其從XML文檔中獲取DOM文檔實例。 DocumentBuilder的實例我們可以通過DocumentBuilderFactory類的newDocumentBuilder()方法得 到。之后就通過DocumentBuilder類的parse(InputStream is)方法將給定文件的內容解析為一個XML文檔,并且返回一個新的DOM Document 對象。具體步驟如下: File file = new File("D:\\編碼\\xml\\domxml.xml"); DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); try { DocumentBuilder db = dbf.newDocumentBuilder(); Document dt = db.parse(file); } catch (Exception e) { // TODO 自動生成 catch 塊 e.printStackTrace(); } 這 時我們就可以開始解析文檔了。通過NodeList,Node分別可以得到節點列表和節點了。NodeList可以由Document對象的 getElementsByTagName("元素名稱");來得到你想得到的哪個元素的節點列表。由NodeList的item(整形參數)方法來得到 節點。通過Node的getFirstChild().getNodeValue()方法可以得到文本節點值。方法如下: NodeList nl = dt.getElementsByTagName("star");//star為一個元素名稱 Node nd = nl.item(0);//得到節點列表 nl 的第一個節點。 此外我們可以通過循環來取得節點列表中所有的節點。 當一個元素有子元素時我們可以通過父節點列表取得子節點列表。方法如下: NodeList nlF = dt.getElementsByTagName("star"); //star為一個元素名稱 Node ndF = nl.item(0); //得到節點列表 nl 的第一個節點。 for(int i = 0; i < nlF.getLength(); i ++) { Node ndF = nlF.item(i); //取得元素的所有節點 NodeList nlC = ndF.getChildNodes(); //取得子元素的節點列表 for(int j = 0; j < nlC.getLength(); j ++) { Node ndC = nlC.item(j); if(ndC.getNodeType()==ndC.ELEMENT_NODE){ String str = ndC.getFirstChild().getNodeValue(); //取得文本節點 System.out.println(str); //打印出文本節點 } } } } /** 注意*/ 由于通過父節點列表得到子節點列表而得到的子元素節點包含了空格所占有的節點,所以這里需要用if(ndC.getNodeType()== ndC.ELEMENT_NODE)來做判斷是否取得的是元素節點(ndC.getNodeType()為節點類型,ndC.ELEMENT_NODE節 點類型為元素節點(注:文本節點是元素節點的一個子節點))。 2. 最常用的SAX解析器是JAXP。JAXP是作為javax.xml包提供的,包括SAX和DIM的Java接口以及Java XML解析器必須是實現的基本接口和類。通過繼承DefaultHandle類實現此類方法則可以遍歷XML文檔: void startDocument() //接收文檔開始的通知 void endDocument() //接收文檔結束的通知 void startElement(String uri,String localName,String qName, Attributes attributes) //接收元素開始的通知 void endElement(String uri,String localName, String qName) //接收元素結束的通知 void characters(char[] ch,int start, int length) //接收字符數據的通知 獲取SAX解析器的方法和DOM相似。獲取SAX解析器的方法如下: SAXParserFactory spf = SAXParserFactory.newInstance(); //得到工廠的一個新實例 try { SAXParser sp = spf.newSAXParser(); //得到SAXParser類的實例 File file = new File("E:\\yuxin_document\\xml\\mytest.xml"); //XML文件 SaxHandle handle = new SaxHandle(); //SaxHandle 這是一個繼承了DefaultHandle的實現了XML遍歷 的一個自定義的類 sp.parse(file, handle); //解析一個XML文檔 } catch (ParserConfigurationException e) { // TODO 自動生成 catch 塊 e.printStackTrace(); } catch (SAXException e) { // TODO 自動生成 catch 塊 e.printStackTrace(); } catch (IOException e) { // TODO 自動生成 catch 塊 e.printStackTrace(); } ** 為了能夠清晰的顯示出XML中的內容,我們還需要將解析后取得的內容顯示在GUI上。一般用表格來實現。 SAX和DOM的合用 我們可以用SAX來解析XML再用DOM來將解析后的數據寫成一個XML文件. 使用DOM創建一個XML文件的方法如下: 首先,需要得到一個寫入XML文件的Document對象: Document doc = DocumentHelper.createDocument(); 然后就可以在這個文檔中添加內容了,如: Element root = doc.addElement("root"); //寫入一個根元素"root" Element el = root.addElement("子元素"); //在根元素中寫入一個子元素 當將所有信息寫入文檔后則可以將Document寫入XML文件中了,方法如下: FileWriter file = new FileWriter("D:\\doc.xml"); //得到一個文件輸出流對象 document.write(file); //將文檔內容寫入文件中(document是上面所得到的Document 對象) 這是一種簡單的寫入方式 如果你想格式化XML文件則可以這樣做: FileOutputStream fos = new FileOutputStream("D:\\doc.xml"); // 得到一個文件輸出流對象 OutputFormat format = OutputFormat.createPrettyPrint(); //得到OutputFormat 格式化類的對象 XMLWriter xw = new XMLWriter(fos,format); //得到XML輸出流XMLWriter接口的一 個實例 xw.write(doc); //將文檔寫入XML fos.close(); //關閉輸出流 xw.close(); |