DOM&SAX解析XML

  在上一篇隨筆中分析了xml以及它的兩種驗證方式。咱們有了xml,可是裏面的內容要怎麼才能獲得呢?若是得不到的話,那麼仍是沒用的,解析xml的方式主要有DOMSAX,其中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 }
DOM

 

輸出結果:對象

固然你能夠直接輸出內容,不用控制格式。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 }
Sax

 

輸出結果:

這裏我也是直接輸出xml的內容,並無寫到硬盤,在實際應用時你能夠把內容存在Map中。

總結:

  經過上面的兩個解析實例,咱們能夠看出DOM解析XML時,首先將xml文檔整個加載到內存中,而後就能夠隨機訪問內存中的文檔對象樹(dom解析器是把xml解析成樹形結構的)。SAX是基於事件的並且是順序的,就是讀到某個標籤時就會調用相應的方法,一旦通過了某個元素以後,咱們就沒辦法再去訪問了。DOM因爲要把整個xml加載到內存中,因此當xml很大時,內存就可能會溢出,而SAX不用事先把xml文檔加載到內存中,佔用內存小,相對而言SAX是面向xml的簡單APIs,在開發上比較複雜,要開發者去實現事件處理器,但會更靈活,而DOM會更易於理解和開發。對於大型的xml文檔,咱們一般會使用SAX的方式去解析。

相關文章
相關標籤/搜索