XML現在已經成為一種通用的資料交換格式,它的平台無關性,語言無關性,系統無關性,給Data Integration與互動帶來了極大的方便。今天主要是介紹java中常用的四種解析XML的方法.
假設我們XML的內容和結構如下:
<?xml version="1.0" encoding="UTF-8"?><HD> <disk name="C"> <capacity>4G</capacity> <directories>100</directories> <files>1580</files> </disk> <disk name="D"> <capacity>10G</capacity> <directories>300</directories> <files>1500</files> </disk> </HD>
一.DOM
用DOM來解析XML檔案的操作比較簡單,它的解析過程是先將XML檔案讀入記憶體,建立一棵文檔樹,通過對這顆文檔樹來操作來完成對XML檔案的操作.
優點:整個文檔樹在記憶體中,便於操作;支援刪除、修改、重新排列等多種功能;
缺點:將整個文檔調入記憶體(包括無用的節點),浪費時間和空間;使用場合:一旦解析了文檔還需多次訪問這些資料;硬體資源充足(記憶體、CPU),且操作資料時要做大量的遍曆樹的操作,這對於大量資料的存取,修改操作率不高,但是對於小資料的一般性應用場合,用DOM來處理已經足夠.
DOM解析:
package DOM;import javax.xml.parsers.DocumentBuilder;import javax.xml.parsers.DocumentBuilderFactory;import org.w3c.dom.Document;import org.w3c.dom.Element;import org.w3c.dom.NodeList;public class domXml {public static void main(String[] args) throws Exception{//得到DOM解析器的工廠執行個體DocumentBuilderFactory dbFactory=DocumentBuilderFactory.newInstance();//從DOM工廠中獲得DOM解析器DocumentBuilder dbBuilder=dbFactory.newDocumentBuilder();//聲明為file為了識別中文名Document document=null;document=dbBuilder.parse("D:/app/AnalysisXML/src/DOM/test.xml");//得到文檔名稱為test的元素的節點列表NodeList list =document.getElementsByTagName("disk");//遍曆該集合,顯示結合中的元素及其子項目的名字for(int i=0;i<list.getLength();i++){Element element=(Element)list.item(i);String name=element.getAttribute("name"); String capacity=element.getElementsByTagName("capacity").item(0).getFirstChild().getNodeValue(); String directories=element.getElementsByTagName("directories").item(0).getFirstChild().getNodeValue(); String files=element.getElementsByTagName("files").item(0).getFirstChild().getNodeValue(); System.out.println("磁碟資訊:"); System.out.println("分區盤符:"+name); System.out.println("分區容量:"+capacity); System.out.println("目錄數:"+directories); System.out.println("檔案數:"+files); System.out.println("-----------------------------------"); }}}
二.SAX
SAX是Simple API for XML的縮寫,這並非官方標準,而是由網上社區討論而產生的標準,幾乎所有的XML解析器都會支援.SAX是指一種介面,或者一個軟體包。也即XML簡單應用程式介面。與DOM不同,SAX提供的訪問模式是一種順序模式,這是一種快速讀寫XML資料的方式,用SAX解析XML檔案,無須將文檔讀入記憶體.當使用SAX分析器對XML文檔進行分析時,會觸發一系列事件,並啟用相應的事件處理函數,應用程式通過這些事件處理函數實現對XML文檔的訪問,因此使用者所需要做的工作就是在相應的事件方法中加入程式碼.因而SAX介面也被稱作事件驅動介面。
SAX解析:
test.java
package DOM;public class test {private String name;private String capacity;private String directories;private String files;public String Getname(){return name;}public void Setname(String name){this.name=name;}public String Getcapacity(){return capacity;}public void Setcapacity(String capacity){this.capacity=capacity;}public String Getdirectories(){return directories;}public void Setdirectories(String directories){this.directories=directories;}public String Getfiles(){return files;}public void Setfiles(String files){this.files=files;}}
SAX 解釋XML:
package DOM;import java.io.InputStream;import java.util.ArrayList; import java.util.List; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; import DOM.test;public class Saxxmltest {public static void main(String[] args) throws Exception { //解析器的擷取 //1、擷取sax解析工廠 SAXParserFactory sf = SAXParserFactory.newInstance(); //2、擷取解析器 SAXParser sp = sf.newSAXParser(); //建立xml檔案的輸入資料流 InputStream inStream = SaxParseService.class.getClassLoader().getResourceAsStream("DOM/test.xml"); //3、解析xml檔案,將事件處理器傳入。 sp.parse(inStream, new Myhander()); }}class Myhander extends DefaultHandler{private List<test> hd=null;private test disk=null;private String preTag =null; //作用是記錄解析時的上一個節點名稱public void startDocument() throws SAXException{hd=new ArrayList<test>();}public void startElement(String uriString,String localName,String qName,Attributes attributes) throws SAXException{if("disk".equals(qName)){disk=new test ();disk.Setname(attributes.getValue(0));}preTag=qName;}public void characters(char[] ch,int start,int length)throws SAXException{if(preTag!=null){String contentString=new String(ch,start,length ); if("capacity".equals(preTag)){ disk.Setcapacity(contentString);} else if("directories".equals(preTag)){ disk.Setdirectories(contentString);}else if("files".equals(preTag)){ disk.Setfiles(contentString);}}}public void endElement(String uri,String localName,String qName) throws SAXException{if("disk".equals(qName)){hd.add(disk );disk=null;}preTag=null;}public void endDocument() throws SAXException { for (test disk : hd) { System.out.println("磁碟資訊:"); System.out.println("分區盤符:"+disk.Getname()); System.out.println("分區容量:"+disk.Getcapacity()); System.out.println("目錄數:"+disk.Getdirectories()); System.out.println("檔案數:"+disk.Getfiles()); System.out.println("-----------------------------------"); }} }
三.DOM4j
DOM4J是一個非常非常優秀的Java XML API,具有效能優異、功能強大和極端易用使用的特點,同時它也是一個開放原始碼的軟體。dom4j的開發包中包含一些第三方開發包,當調用dom4j某些功能需要添加相應的開發包,大部分情況下,在項目中匯入基本的dom4j.jar即可。
DOM4J解析:
package DOM;import java.util.Iterator; import org.apache.naming.java.javaURLContextFactory;import org.dom4j.Document; import org.dom4j.Element; import org.dom4j.io.SAXReader; public class Dom4jXML {public static void main(String[] args) throws Exception{//建立檔案對象java.io.File file=new java.io.File("D:/app/AnalysisXML/src/DOM/test.xml");//建立一個讀取XML檔案的對象SAXReader reader=new SAXReader();//建立一個文檔對象Document document=reader.read(file);//擷取檔案的根節點Element element=document.getRootElement();for(Iterator i=element.elementIterator("disk");i.hasNext();){//擷取節點元素element =(Element)i.next();String name=element.attributeValue("name"); String capacity=element.elementText("capacity");//取disk子項目capacity的內容 String directories=element.elementText("directories"); String files=element.elementText("files"); System.out.println("磁碟資訊:"); System.out.println("分區盤符:"+name); System.out.println("分區容量:"+capacity); System.out.println("目錄數:"+directories); System.out.println("檔案數:"+files); System.out.println("-----------------------------------"); }}}
四.JDOM
jdom解析xml,是基於樹型結構,其利用的是純java技術,實現對xml文檔的各種操作。jdom可以說是直接為java編程服務的,把sax與dom的功能有效結合起來。JDOM應用程式的長度通常是DOM應用程式的三分之一,大約是SAX應用程式的一般.
優點:20-80原則,極大減少了代碼量。
使用場合:要實現的功能簡單,如解析、建立等,但在底層,JDOM還是使用SAX(最常用)、DOM、Xanan文檔。
JDOM解析XML:
package DOM;import java.util.List;import javax.servlet.jsp.PageContext;import org.jdom.*;import org.jdom.input.*; public class JDomXML {public static void main (String[] args)throws Exception{SAXBuilder sBuilder=new SAXBuilder();Document document=sBuilder.build("src/DOM/test.xml"); //構造文檔對象 Element rootElement=document.getRootElement();//擷取根項目List<Element> list=rootElement.getChildren("disk");//擷取名字為disk的所有元素for(int i=0;i<list.size();i++) //遍曆根項目的子項目集合{Element element=(Element)list.get(i);String name=element.getAttributeValue("name"); String capacity=element.getChildText("capacity");//取disk子項目capacity的內容 String directories=element.getChildText("directories"); String files=element.getChildText("files"); System.out.println("磁碟資訊:"); System.out.println("分區盤符:"+name); System.out.println("分區容量:"+capacity); System.out.println("目錄數:"+directories); System.out.println("檔案數:"+files); System.out.println("-----------------------------------"); }}}
五.解析結果
六.總結
XML在不同的語言裡解析方式都是一樣的,只不過實現的文法不同而已。XML的解析,可以更加自己的資料量的大小,選擇不同的解析類型,同時提高解析效率!