在上一篇隨筆中分析了xml以及它的兩種驗證方式。咱們有了xml,可是裏面的內容要怎麼才能獲得呢?若是得不到的話,那麼仍是沒用的,解析xml的方式主要有DOM跟SAX,其中DOM是W3C官方的解析方式,而SAX是民間(非官方)的,兩種解析方式是很不同的。下面經過例子來分析兩種解析方式的區別。java
下面是要解析的xml文檔node
1 <?xml version="1.0" encoding="utf-8"?> 2 <學生名冊> 3 <!--http://www.cnblogs.com/zhi-hao/--> 4 <學生 學號="A1"> 5 <姓名>CIACs</姓名> 6 <性別>男</性別> 7 <年齡>22</年齡> 8 </學生> 9 <學生 學號="A2"> 10 <姓名>zhihao</姓名> 11 <性別>男</性別> 12 <年齡>23</年齡> 13 </學生> 14 </學生名冊>
DOM(Document Object Model)文檔對象模式,從名字上就能夠知道,DOM應該是基於文檔對象來解析的。在DOM解析方式中主要用到了如下四個接口dom
一、Document接口,該接口是對xml文檔進行操做的入口,要想操做xml,必須得到文檔的入口。ide
二、Node接口,存儲xml文檔的節點的ui
三、NodeList接口spa
四、NameNodeMap接口,存儲的是xml中的屬性。code
DOM中的基本對象有Document,Node,NodeList,Element和Attr。有了這些就能夠解析xml了xml
1 package xmlTest; 2 3 import java.io.File; 4 5 import javax.xml.parsers.DocumentBuilder; 6 import javax.xml.parsers.DocumentBuilderFactory; 7 8 import org.w3c.dom.Attr; 9 import org.w3c.dom.Document; 10 import org.w3c.dom.Element; 11 import org.w3c.dom.NamedNodeMap; 12 import org.w3c.dom.Node; 13 import org.w3c.dom.NodeList; 14 /** 15 * 16 * @author CIACs 17 * 2014-09-22 18 */ 19 20 public class DOM { 21 22 public static void main(String[] args) throws Exception { 23 //得到解析工廠實例 24 DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 25 //經過工廠得到DocumentBulider 26 DocumentBuilder db = dbf.newDocumentBuilder(); 27 //得到文檔對象的入口 28 Document doc = db.parse(new File("student.xml")); 29 //得到根元素 30 Element root = doc.getDocumentElement(); 31 //開始解析 32 parseElement(root); 33 } 34 private static void parseElement(Element element) 35 { 36 String tagName = element.getNodeName(); 37 System.out.print("<"+tagName); 38 //得到元素屬性 39 NamedNodeMap map = element.getAttributes(); 40 if(null != map) 41 { 42 for(int i = 0;i < map.getLength();i++) 43 { 44 Attr attr = (Attr)map.item(i); 45 String attrName = attr.getName(); 46 String attrValue = attr.getValue(); 47 System.out.print(" "+attrName + "=\""+attrValue+"\""); 48 } 49 } 50 System.out.print(">"); 51 52 //得到元素的孩子節點 53 NodeList child = element.getChildNodes(); 54 55 for(int i = 0;i < child.getLength();i++) 56 { 57 Node node = child.item(i); 58 //判斷節點類型 59 60 short nodeType = node.getNodeType(); 61 62 if(nodeType == Node.ELEMENT_NODE) 63 { 64 parseElement((Element)node); 65 } 66 else 67 if(nodeType == Node.TEXT_NODE) 68 { 69 System.out.print(node.getTextContent()); 70 } 71 else 72 if(nodeType == Node.COMMENT_NODE) 73 { 74 System.out.print("<!--"+node.getTextContent()+"-->"); 75 } 76 } 77 System.out.print("</"+tagName+">"); 78 } 79 }
輸出結果:對象
固然你能夠直接輸出內容,不用控制格式。blog
SAX(Simple APIs for XML)面向xml的簡單APIs。SAX解析xml的通常步驟以下
一、建立SAXParserFactory對象; SAXParserFactory spf = SAXParserFactory.newInstance();
二、使用上面建立的工廠對象建立SAXParser解析對象;SAXParser sp = spf.newSAXParser();
三、建立SAXHandler處理器,而這個SAXHandler類要繼承DefaultHandler,本身從新編寫其中的方法,主要有 public void startElement(String uri, String localName, String qName,Attributes attributes) throws SAXException{ } 這個方法是在讀取xml數據的節點元素開始時觸發,須要實現這個方法進行標記元素的名字的操做; public void characters(char[] ch, int start, int length)throws SAXException{ } 這個方法能夠處理節點之間的數據; public void endElement(String uri, String ocalName, String qName)throws SAXException { } 這個方法在處理節點元素終止時觸發,可添加代碼來將節點數據進行存儲。
下面是解析xml的代碼
1 package xmlTest; 2 3 import java.io.File; 4 import javax.xml.parsers.SAXParser; 5 import javax.xml.parsers.SAXParserFactory; 6 7 import org.xml.sax.Attributes; 8 import org.xml.sax.SAXException; 9 import org.xml.sax.helpers.DefaultHandler; 10 11 /** 12 * 13 * @author CIACs 14 * 2014-09-22 15 */ 16 17 public class Sax { 18 public static void main(String []args) 19 { 20 try 21 { 22 //得到sax解析工廠實例 23 SAXParserFactory spf = SAXParserFactory.newInstance(); 24 //得到sax解析器 25 SAXParser sp = spf.newSAXParser(); 26 //得到SAXHandler,該類是繼承自DefaultHandler的 27 SAXHandler handler = new SAXHandler(); 28 //開始解析xml文檔 29 sp.parse(new File("student.xml"), handler); 30 31 } 32 catch(Exception e) 33 { 34 e.printStackTrace(); 35 } 36 } 37 38 } 39 40 class SAXHandler extends DefaultHandler 41 { 42 private String currentElement; 43 private String currentValue; 44 private String attrName; 45 private String attrValue; 46 @Override 47 public void startElement(String uri, String localName, String qName, 48 Attributes attributes) throws SAXException { 49 currentElement = qName; 50 for(int i = 0;i < attributes.getLength();i++) 51 { 52 attrName = attributes.getQName(i); 53 attrValue = attributes.getValue(i); 54 System.out.println("屬性: "+ attrName + "=" + attrValue); 55 } 56 57 } 58 @Override 59 public void characters(char[] ch, int start, int length) 60 throws SAXException { 61 currentValue = new String(ch,start,length); 62 } 63 @Override 64 public void endElement(String uri, String localName, String qName) 65 throws SAXException { 66 67 if(currentElement.equals(qName)) 68 { 69 System.out.println(currentElement + "=" + currentValue); 70 } 71 } 72 }
輸出結果:
這裏我也是直接輸出xml的內容,並無寫到硬盤,在實際應用時你能夠把內容存在Map中。
總結:
經過上面的兩個解析實例,咱們能夠看出DOM解析XML時,首先將xml文檔整個加載到內存中,而後就能夠隨機訪問內存中的文檔對象樹(dom解析器是把xml解析成樹形結構的)。SAX是基於事件的並且是順序的,就是讀到某個標籤時就會調用相應的方法,一旦通過了某個元素以後,咱們就沒辦法再去訪問了。DOM因爲要把整個xml加載到內存中,因此當xml很大時,內存就可能會溢出,而SAX不用事先把xml文檔加載到內存中,佔用內存小,相對而言SAX是面向xml的簡單APIs,在開發上比較複雜,要開發者去實現事件處理器,但會更靈活,而DOM會更易於理解和開發。對於大型的xml文檔,咱們一般會使用SAX的方式去解析。