在Android系统中,对于XML文件的读取主要采用的是SAX方法。SAX是一个用于处理XML事件驱动的“推”模型,虽然它不是W3C标准,但它却是一个得到了广泛认可的API。SAX解析器不像DOM那样建立一个完整的文档树,而是在读取文档时激活一系列事件,这些事件被推给事件处理器,然后由事件处理器提供对文档内容的访问。  
常见的事件处理器有三种基本类型:  
  a. 用于访问XML DTD内容的DTDHandler; 
  b. 用于低级访问解析错误的ErrorHandler;  
  c. 用于访问文档内容的ContentHandler,这也是最普遍使用的事件处理器。
  因为SAX具有边扫描边读取的特性,无需将整个文件读入内存中,更好的节省了移动设备中的资源。但是这种方法对于操作节点显得略有复杂。
  下面以本人在学习中所看过的一个视频教程中的实例,说明Android应用程序对于XML文档的解析过程。

  用于开启解析的Activity:

 

  1. public class XMLActitity extends Activity { 
  2.     /** Called when the activity is first created. */ 
  3.     private Button parseButton ; 
  4.     @Override 
  5.     public void onCreate(Bundle savedInstanceState) { 
  6.         super.onCreate(savedInstanceState); 
  7.         setContentView(R.layout.main); 
  8.         parseButton = (Button)findViewById(R.id.parseButton); 
  9.         parseButton.setOnClickListener(new ParseButtonListener()); 
  10.     } 
  11.     //设定监听器,当点击按钮时,开始进行解析。 
  12.     class ParseButtonListener implements OnClickListener{ 
  13.  
  14.         @Override 
  15.         public void onClick(View v) { 
  16.             HttpDownloader hd = new HttpDownloader(); 
  17. //将网络上的一个XML资源下载并解析成为一个字符串,这里的解析在一个外部类中进行,这里不再列出。
  18.             String resultStr = hd.download("http://192.168.1.107:8081/voa1500/test.xml"); 
  19.             System.out.println(resultStr); 
  20.             try
  21. //下面是解析XML的
  22.                 //1. 创建一个SAXParserFactory 
  23.                 SAXParserFactory factory = SAXParserFactory.newInstance(); //2. 获得一个XMLReader 
  24.                 XMLReader reader = factory.newSAXParser().getXMLReader(); 
  25.                 //3. 为XMLReader设置内容处理器 
  26.                 reader.setContentHandler(new MyContentHandler()); 
  27.                 //4.开始解析文件。注意这个方法的参数,需要是输入流。还有另外一种不同参数,需要时系统内部资源的URI 
  28.                 reader.parse(new InputSource(new StringReader(resultStr))); 
  29.                  
  30.             } 
  31.             catch(Exception e){ 
  32.                 e.printStackTrace(); 
  33.             } 
  34.         } 
  35.          
  36.     } 

 

  内容处理器:

  SAX时间作为驱动的解析模型,需要相应的事件处理函数。SAX将不同的事件处理函数按照类型分不同接口中。对于文件内容的处理函数,在内容处理器接口(ContentHandler)中。

 

  1. public class MyContentHandler extends DefaultHandler { 
  2.     String hisname, address, money, sex, status; 
  3.     String tagName; 
  4.  
  5. //当开始解析文档时,触发这个函数
  6.     public void startDocument() throws SAXException { 
  7.         System.out.println("````````begin````````"); 
  8.     } 
  9.   //当结束解析文档时,触发这个函数
  10.     public void endDocument() throws SAXException { 
  11.         System.out.println("````````end````````"); 
  12.     } 
  13.   //当扫描到开始标签时,触发这个函数。
  14.     public void startElement(String namespaceURI, String localName, 
  15.             String qName, Attributes attr) throws SAXException { 
  16.         //使用全局变量tagName作为当前正在解析节点的标记。
  17. tagName = localName; 
  18.         if (localName.equals("worker")) { 
  19.             //获取标签的全部属性。标签的所有属性存储在数组中。 
  20.             for (int i = 0; i < attr.getLength(); i++) {
  21. //打印其中某个属性的名称和属性值 
  22.                 System.out.println(attr.getLocalName(i) + "=" + attr.getValue(i)); 
  23.             } 
  24.         } 
  25.     } 
  26.  
  27.     public void endElement(String namespaceURI, String localName, String qName) 
  28.             throws SAXException { 
  29.         //在workr标签解析完之后,会打印出所有得到的数据 
  30.         tagName = ""
  31.         if (localName.equals("worker")) { 
  32.             this.printout(); 
  33.         } 
  34.     } 
  35. //当扫描到标签内容时,触发这个函数。标签的内容存储在字符数组中。
  36.     public void characters(char[] ch, int start, int length) 
  37.             throws SAXException { 
  38. //首先判断当前扫描到的标签,然后根据当前标签判断标签内容
  39.         if (tagName.equals("name")) 
  40.             hisname = new String(ch, start, length); 
  41.         else if (tagName.equals("sex")) 
  42.             sex = new String(ch, start, length); 
  43.         else if (tagName.equals("status")) 
  44.             status = new String(ch, start, length); 
  45.         else if (tagName.equals("address")) 
  46.             address = new String(ch, start, length); 
  47.         else if (tagName.equals("money")) 
  48.             money = new String(ch, start, length); 
  49.     } 
  50.  
  51.     private void printout() { 
  52.         System.out.print("name: "); 
  53.         System.out.println(hisname); 
  54.         System.out.print("sex: "); 
  55.         System.out.println(sex); 
  56.         System.out.print("status: "); 
  57.         System.out.println(status); 
  58.         System.out.print("address: "); 
  59.         System.out.println(address); 
  60.         System.out.print("money: "); 
  61.         System.out.println(money); 
  62.         System.out.println(); 
  63.     } 
  64.  

   在上面程序中,需要注意,我们并非实现了ContentHandler接口,而是继承了已经实现该接口的DefaultHandler。我再付类中已经实现了接口中所有方法,并将方法实现为空方法,我们继承父类只需要重写那些我们需要的方法即可。