SAX中解析XML的例子一搜一大把,這就只是列出解析中需要注意的地方。首先看下面一個xml
這是一個很常見的xml檔案,如果你用dom解析的話,不會有什麼大問題,頂多有個字元集的問題,但是由於SAX是基於事件解析的,所以每當遇到開始標籤,內容,結束標籤,注釋,dtd聲明,實體等都會產生一個相應的事件。但是基於SAX來解析,遇到斷行符號符,空格,tab鍵產生的空格都會觸發characters事件。是不是還沒看出來?不要急,其實比如說name標籤結束後是有一個斷行符號符,在下一個標籤sex到來之前還有幾個tab鍵產生的空格,這些都會觸發characters事件。
我們解析的時候一個較好的方法就是遇到開始節點用一個臨時變數tagName儲存當前標籤名。如果tagName等於某個標籤的名字則給相應的欄位賦值,這其中就會有個問題,就是上面紅色標記的。如果在標籤結束事件時沒有及時給tagName清空,那麼結束標籤後的tab,斷行符號符將會觸發characters事件。那麼會覆蓋你之前在characters中的賦值,這些值會被空格覆蓋,相當於清空。
其實這不是什麼大的技巧,但是如果沒和上面所說的聯想在一起,還是要花點時間來發現這個問題的。網上說用stringbuilder,其實這個也是治標不治本,空格什麼的也會被append上。所以最好還是把tagName=””,這樣characters事件中就沒有任何一個標籤和它匹配了,所以也就不會覆蓋到原來的有效值
下面貼上代碼
packagecom.oppo; importorg.xml.sax.Attributes;importorg.xml.sax.SAXException;importorg.xml.sax.helpers.DefaultHandler; importandroid.util.Log; public classMyContentHandler extends DefaultHandler { private static final String TAG ="MyContentHandler"; String hisName, address, money, sex,status; String tagName; StringBuilder sb = new StringBuilder(); private String tempStr = ""; @Override public void startDocument() throwsSAXException { Log.d(TAG,"------begin-------"); } @Override public void endDocument() throwsSAXException { Log.d(TAG, "-------end-------"); } @Override public void startElement(String uri, StringlocalName, String qName,Attributes attributes) throws SAXException { tagName = localName; if(localName.equals("worker")) { for (int i = 0; i < attributes.getLength();i++) { Log.d(TAG,attributes.getLocalName(i) + "=" +attributes.getValue(i)); } } } @Override public void endElement(String uri, StringlocalName,String qName) throws SAXException { if(localName.equals("worker")){ Log.d(TAG, "name:" +hisName + "\nsex:" + sex + "\nstatus:" +status + "\naddress:" +address + "\nmoney:" + money); } //防止標籤結束後的空格引起的characters事件覆蓋原來的值 //如果不讓它等於Null 字元串,那麼結束標籤後面的空格會引發characters事件, //此時下一個startElement事件還沒有開始,tagName還在是上一個//startElement事件中的 //標籤名,上一個characters中的對應的標籤名的值勢必會被空格覆蓋。 tagName ="";//這一句很重要 } @Override public void characters(char[] ch, intstart, int length) throws SAXException { tempStr = new String(ch, start, length); if(tagName.equals("name")){ hisName = tempStr; }elseif(tagName.equals("sex")){ sex = tempStr; }elseif(tagName.equals("status")){ status = tempStr; }elseif(tagName.equals("address")){ address = tempStr; }elseif(tagName.equals("money")){ money = tempStr; } }}