XML 之解析之SAX解析器

一、        前言



用 Java解析XML文檔,最常用的有兩種方法:使用基於事件的XML簡單API(Simple API for XML)稱爲SAX和基於樹和節點的文檔對象模型(Document Object Module)稱爲DOM。Sun公司提供了Java API for XML Parsing(JAXP)接口來使用SAX和DOM,通過JAXP,我們可以使用任何與JAXP兼容的XML解析器。


JAXP接口包含了三個包:


(1)       org.w3c.dom  W3C推薦的用於XML標準規劃文檔對象模型的接口。


(2)       org.xml.sax   用於對XML進行語法分析的事件驅動的XML簡單API(SAX)


(3)       javax.xml.parsers解析器工廠工具,程序員獲得並配置特殊的特殊語法分析器。
javax包 相對於 java包 佔用資源比較少

二、        前提



DOM編程不要其它的依賴包,因爲JDK裏自帶的JDK裏含有的上面提到的org.w3c.dom、org.xml.sax 和javax.xml.parsers包就可以滿意條件了。


三、        使用SAX解析XML文檔



SAX是基於事件的簡單API,同樣的我們也是用一個最簡單的例子來看看SAX是如何解析XML的


先來看看我們要解析的XML代碼吧


<?xml version="1.0" encoding="gb2312"?>


<books>


  <book email=“alexlee”>


             <name addr="address">kunshan</name>


             <price>10</price>


  </book>


</books>


簡單的不能再簡單了。但是該有的都有了,根元素、屬性、子節點。好了,能反應問題就行了,下面來看看解析這個XML文件的Java代碼吧!




這段代碼比較短,因爲SAX是事件驅動的,它的大部分實現在在另一個Java文件中,先別管另一個文件,我們來一個個地分析吧!


(1)得到SAX解析器的工廠實例



3            SAXParserFactory saxfac=SAXParserFactory.newInstance();


這是一個javax.xml.parsers.SAXParserFactory類的實例


(2)從SAX工廠實例中獲得SAX解析器



5            SAXParser saxparser=saxfac.newSAXParser();


使用javax.xml.parsers.SAXParserFactory工廠的newSAXParser()方法


(3)把要解析的XML文檔轉化爲輸入流,以便DOM解析器解析它



6                   InputStream is=new FileInputStream("bin/library.xml");


InputStream是一個接口。


(4)解析XML文檔



7                   saxparser.parse(is,new MySAXHandler());


後面就不用看了,都是些沒用的代碼(相對而言),夠簡單的吧!


注意了,我們新建了一個實例new MySAXHandler()這個實例裏面又有什麼東西呢?


這個實例就是SAX的精華所在。我們使用SAX解析器時,必須實現內容處理器ContentHandler接口中的一些回調方法,然而我們不須要全部地實現這些方法,還好,我們有org.xml.sax.helpers.DefaultHandler類,看它的類申明:


public class DefaultHandler


implements EntityResolver, DTDHandler, ContentHandler, ErrorHandler


實現了這麼多接口啊,其它的先不管了,至少它實現了ContentHandler這一接口。




不要看它一大堆,我一一分解給大家看。我們說SAX是基於事件的API,我們這個類實到了ContentHandler接口中的如下方法:


(1)startDocument()  用於處理文檔解析開始事件

    只被執行一次


     public void startDocument() throws SAXException {


               System.out.println("文檔開始打印了");


        }


(2)endDocument()  用於處理文檔解析結束事件

    只被執行一次
      public void endDocument() throws SAXException {


              System.out.println("文檔打印結束了");


        }


(3)startElement  用於處理元素開始事件

    遇到開始標籤被觸發
     public void startElement(String uri, String localName, String qName,


                     Attributes attributes) throws SAXException {


              if(qName.equals("books")){


                     return;


              }


              if(qName.equals("book")){


                     System.out.println(attributes.getQName(0)+attributes.getValue(0));


              }


              if(attributes.getLength()>0){


                     this.attributes=attributes;


                     this.hasAttribute=true;


              }


       }


第二個參數String qName表示這個元素的名字,如:


根節點 <books></books> 它的qName爲“books”


最底層節點 <price>jjjjjj</price> 它的qName爲“price”


知道這一點上面程序就好解釋了,當遇到根元素“books”時就什麼也不做跳過,當遇到“book”元素時就打出它的屬性(它只有一個屬性<book email="zhoujunhui"></book>)。


當是其它節點時(這下只剩下最底層的兩個節點“name”和“price”了),就把它的屬性取出來存到this.attributes域中,以後中元素結束事件好處理。


(4)endElement 用於處理元素結束事件

    遇到結束標籤被觸發
     public void endElement(String uri, String localName, String qName)


                     throws SAXException {


              if(hasAttribute&&(attributes!=null)){


                     for(int i=0;i<attributes.getLength();i++){


                            System.out.println(attributes.getQName(0)+attributes.getValue(0));


                     }


              }


       }


代碼的作用是如果這個元素的屬性不爲空(hasAttribute&&(attributes!=null)),就把它們打印出來。


(5)characters(char[] ch, int start, int length) 處理元素字符的內容

    <></> 之間遇到任何 "回車符" "空格符"或其他"不爲空"的字符
    都將觸發characters 方法,兩個標籤之間的部分,不論有多少
    空格 回車 字符  都只能觸發一次characters方法
charachers(char [] ch,int start,int length):當遇到xml內容時觸發這個方法,
用new String(ch,start,length)可以接受內容
              public void characters(char[] ch, int start, int length)


                     throws SAXException {


              System.out.println(new String(ch,start,length));


       }



public class SaxXml {

	public static void main(String[] args) {
		
		SAXParserFactory saxFactory = SAXParserFactory.newInstance();
		
		try {
			SAXParser parser = saxFactory.newSAXParser();
			File file = new File("src/com/xm/inproe.xml");
			parser.parse(file, new MyHander());
			
			
		} catch (ParserConfigurationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SAXException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} 
				
	}
}


class MyHander extends DefaultHandler{
	@Override
	public void characters(char[] ch, int start, int length) throws SAXException {
	
		String a = new String(ch, start, length);
		System.out.print(a);
	}
	@Override
	public void endElement(String uri, String localName, String qName) throws SAXException {

		System.out.print("</"+qName+">");
	}
	@Override
	public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {

		System.out.print("<"+qName+"");
		for (int i = 0; i < attributes.getLength(); i++) {
			String name = attributes.getQName(i);
			String values = attributes.getValue(name);
			System.out.print(" "+name+"=“"+values+"”");
		}
		System.out.print(">");
	}
}


inproe.xml
<?xml version="1.0" encoding="UTF-8"?>
<employees>
    <employee id="1" depName="教學部">
       Text XMl sax
        <name>tom</name>
        <age>18</age>
        <gender>male</gender>
        <salary>200</salary>
        <test>test</test>
    </employee>
    
     <employee id="2" depName="教學部">
        <name>java</name>
        <age>19</age>
        <gender>famale</gender>
        <salary>2050</salary>
    </employee>
    
     <employee id="3" depName="市場部">
        <name>store</name>
        <age>20</age>
        <gender>famale</gender>
        <salary>4000</salary>
    </employee>
    
     
    <employee id="4" depName="市場部">
        <name>buy</name>
        <age>21</age>
        <gender>male</gender>
        <salary>45500</salary>
    </employee>
    
</employees>

控制檯輸出



































































發佈了54 篇原創文章 · 獲贊 71 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章