1.SAX概念
SXA:Simple API for XML
基于事件驱动(Android中的事件驱动基于回调函数),边加载边解析。
五个主要的回调方法:
startDocument() //处理文档解析开始事件
startElement()
//处理元素开始事件
endElement()
//处理元素结束事件
endDocument()
//处理文档结束事件
2.基本步骤
(1)创建SAXParserFactory对象(newInstance())
(2)根据SAXParserFactory对象的newSAXParser()方法创建SAXParser解析器对象
(3)根据SAXParser解析器对象获得事件源对象XMLReader对象
(4)实例化一个DefaultHandler对象
(5)连接事件源对象到事件处理器DefaultHandler中(setContentHandler方法)
(6)使用XMLReader的parse方法解析从输入源中获取的XML数据
(7)通过DefaultHandler返回需要的数据集合
3.实例
需要解析的xml文档
<?xml version="1.0" encoding="utf-8"?> <students> <student id="0"> <name>zhangmq</name> <gender>female</gender> <age>24</age> </student> <student id="1"> <name>zhouhy</name> <gender>male</gender> <age>24</age> </student> </students>
根据xml文档定义的Student类
public class Student { private String id; private String name; private String gender; private String age; public String getId() { return id; } public void setId(String id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getGender() { return gender; } public void setGender(String gender) { this.gender = gender; } public String getAge() { return age; } public void setAge(String age) { this.age = age; } public String toString(){ return "Student [id = "+id+" name = "+name +" gender = "+gender+" age = "+age+"]"; } }具体解析代码
public class SAXParseHandler extends DefaultHandler { List<Student> students; Student student; String nodeName; //记录当前的元素名字 // 处理文档解析开始事件 @Override public void startDocument() throws SAXException { // TODO Auto-generated method stub Log.d("zhangmq","startDocument"); students = new ArrayList<Student>(); } // 处理元素解析开始事件 @Override public void startElement(String uri,String localName,String qName,Attributes attributes) throws SAXException { // TODO Auto-generated method stub Log.d("zhangmq","startElement"); Log.d("zhangmq","startElement localName = " + localName); Log.d("zhangmq","startElement qName = " + qName); Log.d("zhangmq","startElement attributes.getLength() = " + attributes.getLength()); if (localName.equals("student")) { student = new Student(); for (int i = 0; i < attributes.getLength(); i++) { if (attributes.getLocalName(i).equals("id")) { student.setId(attributes.getValue(i)); } } } else { nodeName = localName; } } // 接收字符块通知 @Override public void characters(char[] ch,int start,int length) throws SAXException { // TODO Auto-generated method stub Log.d("zhangmq","characters"); Log.d("zhangmq","characters ch = " + ch); Log.d("zhangmq","characters start = " + start); Log.d("zhangmq","characters length = " + length); //这个地方比较容易失误 //若是不加trim,则str可能是一个空字符串,但它不是普通的null或是"",而是" ". //这样会导致判断str != null && !"".equals(str)的时候失误。千万要注意. //要判断str是因为还会解析</name>,得到的nodeName跟<name>是一样的. String str = String.valueOf(ch,start,length).trim(); Log.d("zhangmq","characters str = " + str); Log.d("zhangmq","characters nodeName = " + nodeName); if (str != null && !"".equals(str)) { if ("name".equals(nodeName)) { student.setName(str); } else if ("gender".equals(nodeName)) { student.setGender(str); } else if ("age".equals(nodeName)) { student.setAge(str); } } } // 接收元素结束通知 @Override public void endElement(String uri,String qName) throws SAXException { // TODO Auto-generated method stub Log.d("zhangmq","endElement"); // 判断标签是否为student if (localName.equals("student")) { students.add(student); } } // 接收文档结束通知 @Override public void endDocument() throws SAXException { // TODO Auto-generated method stub super.endDocument(); Log.d("zhangmq","endDocument"); } public String getStudentsString() { // 再需要+字符串时,str最好定义成"",否则,在显示字符串的时候最前面的是null,例如下面的就是:nullStudent String str = ""; for (int i = 0; i < students.size(); i++) { str = str + students.get(i).toString() + "\n"; } return str; } }解析xml文档
public class SaxParseActivity extends Activity { private TextView sax_parse_tv; @Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); setContentView(R.layout.activity_sax); sax_parse_tv = (TextView) findViewById(R.id.sax_parse); sax_parse_tv.setText(saxParseXml()); } private String saxParseXml() { String str = null; SAXParserFactory factory = null; //解析器对象 SAXParser parse = null; //事件源对象 XMLReader reader = null; InputStream is = null; //SAX解析的帮助类,继承DefaultHandler SAXParseHandler parseHandler = null; //1.实例化SAXParserFactory对象 factory = SAXParserFactory.newInstance(); try { //2.使用SAXParserFactory对象实例化SAXParser对象 parse = factory.newSAXParser(); } catch (ParserConfigurationException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (SAXException e) { // TODO Auto-generated catch block e.printStackTrace(); } try { //3.使用SAXParser对象实例化XMLReader reader = parse.getXMLReader(); } catch (SAXException e) { // TODO Auto-generated catch block e.printStackTrace(); } //自己写的SAX解析帮助类,实例化 parseHandler = new SAXParseHandler(); //解析器注册事件 reader.setContentHandler(parseHandler); try { //获取xml文件到输入流中 is = getResources().getAssets().open("dom_info.xml"); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } InputSource inputSource = new InputSource(is); try { //解析文件,事件源 reader.parse(inputSource); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (SAXException e) { // TODO Auto-generated catch block e.printStackTrace(); } str = parseHandler.getStudentsString(); return str; } }