SAX(Simple API for XML)解析器是一種基於事件的解析器,它的核心是事件處理模式,主要是圍繞着事件源以及事件處理器來工做的。當事件源產生事件後,調用事件處理器相應的處理方法,一個事件就能夠獲得處理。在事件源調用事件處理器中特定方法的時候,還要傳遞給事件處理器相應事件的狀態信息,這樣事件處理器纔可以根據提供的事件信息來決定本身的行爲。java
SAX解析器的優勢是解析速度快,佔用內存少。很是適合在Android移動設備中使用。數組
DefaultHandler:是一個事件處理器,能夠接收解析器報告的全部事件,處理所發現的數據。它實現了EntityResolver接口、DTDHandler接口、ErrorHandler接口和ContentHandler接口。這幾個接口表明不一樣類型的事件處理器。app
利用SAX解析XML,實際上只須要繼承DefaultHandler類,而後重寫幾個關鍵性方法便可。通常咱們須要重寫的方法是startDocument、startElement、characters、endElement和endDocument方法。ide
API解釋:函數
1 import org.xml.sax.Attributes; 2 import org.xml.sax.SAXException; 3 import org.xml.sax.helpers.DefaultHandler; 4 5 public class MyParser extends DefaultHandler{ 6 7 /** 8 * 當文檔開始解析時此函數被調用 9 * 10 * 一般咱們須要在這裏面作一些初始化的工做,好比分配某些資源 11 */ 12 @Override 13 public void startDocument() throws SAXException { 14 super.startDocument(); 15 } 16 17 /** 18 * 當掃描到文檔元素節點起始標誌時被調用 19 * 20 * 一般咱們須要作一下標記,或者分配節點資源。 21 */ 22 @Override 23 public void startElement(String uri, String localName, String qName, 24 Attributes attributes) throws SAXException { 25 super.startElement(uri, localName, qName, attributes); 26 } 27 28 /** 29 * 掃描到元素節點中的字符串內容時調用此函數 30 * @param ch 表明元素內容的字符數組(實測時候並不徹底表示元素內容,不過這不影響) 31 * @param start 可以使用的起始位置 32 * @param length 可以使用的數組長度 33 */ 34 @Override 35 public void characters(char[] ch, int start, int length) 36 throws SAXException { 37 super.characters(ch, start, length); 38 } 39 40 41 /** 42 * 掃描到元素節點結束標誌時調用 43 * 44 * 應該是最重要的一個方法。須要判斷節點名做相應的數據解析。 45 * @param localName 節點名字 46 * @param qName 含限定符的節點名字 47 */ 48 @Override 49 public void endElement(String uri, String localName, String qName) 50 throws SAXException { 51 super.endElement(uri, localName, qName); 52 } 53 54 /** 55 * 掃描文檔結束後調用 56 * 57 * 若是有些資源須要釋放的話,就在這裏作好了。 58 */ 59 @Override 60 public void endDocument() throws SAXException { 61 super.endDocument(); 62 } 63 64 }
須要解析的persons.xml文件內容以下:ui
1 <?xml version="1.0" encoding="UTF-8"?> 2 <persons> 3 <person id="1" group="1"> 4 <name>張三</name> 5 <age>24</age> 6 </person> 7 <person id="2" group="2"> 8 <name>李四</name> 9 <age>25</age> 10 </person> 11 <person id="3" group="1"> 12 <name>王五</name> 13 <age>26</age> 14 </person> 15 </persons>
定義Person實體類:this
/** * Created by Shane on 2015/4/24. */ public class Person { private int id; private int group; private String name; private int age; public int getId() { return id; } public void setId(int id) { this.id = id; } public int getGroup() { return group; } public void setGroup(int group) { this.group = group; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { StringBuilder sb = new StringBuilder(); sb.append("name: " + name); sb.append(", age: " + age); sb.append(", id: " + id); sb.append(", group: " + group); return sb.toString(); } }
定義用於解析XML文件的解析器PersonSAXHandler 類以下:spa
/** * Created by Shane on 2015/4/24. */ public class PersonSAXHandler extends DefaultHandler{ private static final String TAG_PERSON = "person"; private static final String TAG_NAME = "name"; private static final String TAG_AGE = "age"; private List<Person> persons; private Person person; private StringBuffer stringBuffer; public List<Person> getPersons() { return persons; } @Override public void startDocument() throws SAXException { super.startDocument(); persons = new ArrayList<>(); stringBuffer = new StringBuffer(); } @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { super.startElement(uri, localName, qName, attributes); if (localName.equals(TAG_PERSON)) { person = new Person(); person.setId(Integer.parseInt(attributes.getValue(0))); person.setGroup(Integer.parseInt(attributes.getValue(1))); } stringBuffer.setLength(0); // start a new string buffer. } @Override public void characters(char[] ch, int start, int length) throws SAXException { super.characters(ch, start, length); stringBuffer.append(ch, start, length); } @Override public void endElement(String uri, String localName, String qName) throws SAXException { super.endElement(uri, localName, qName); if (localName.equals(TAG_PERSON)) { persons.add(person); } else if (localName.equals(TAG_NAME)) { person.setName(stringBuffer.toString().trim()); } else if (localName.equals(TAG_AGE)) { person.setAge(Integer.parseInt(stringBuffer.toString().trim())); } } @Override public void endDocument() throws SAXException { super.endDocument(); } }
包裝上述PersonSAXHandler類,定義PersonSAXParser類進行解析:code
/** * Created by Shane on 2015/4/24. */ public class PersonSAXParser implements PersonParser{ @Override public List<Person> parse(InputStream inputStream) { List<Person> persons = new ArrayList<>(); try { SAXParser saxParser = SAXParserFactory.newInstance().newSAXParser(); PersonSAXHandler personSAXHandler = new PersonSAXHandler(); saxParser.parse(inputStream, personSAXHandler); persons = personSAXHandler.getPersons(); } catch (ParserConfigurationException e) { e.printStackTrace(); } catch (SAXException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { if (inputStream != null) { try { inputStream.close(); } catch (IOException e) {} } } return persons; } }
PersonParser接口定義以下:xml
/** * Created by Shane on 2015/4/24. */ public interface PersonParser {
public List<Person> parse(InputStream inputStream); }