Android开发进阶(五)----------SAX模式解析XML文件

SAX解析XML:

SAX基本原理:

采用事件驱动解析XML文件,以流式方式逐行的去读,它不需要解析完整个文档,在按内容顺序解析文档的过各中,SAX会判断当前讲到的字符是否合法XML语法中的某部分,如果符合就触发事件(例如startDocument()、endDocument()诸如此类的事件),它的特点是不会记录前面所碰到的标签,并且它是一个解析速度快并且占用内存少的XML解析器,

SAX解析步骤:

1、从SAXPraserFactory中创建一个新的实例

2、再从SAXParserFactory里得到一个新的SAX解析器对象SAXParser

3、再调用SAXParser对象的.parse()方法里面带两个参数一个是输入流一个是DefaultHandler对象这样就可以了。而DefaultHandler是实现了ContentHandler接口的。ContentHandler接口中定义了一系列的方法事件:诸如:

 

public abstractvoid startDocument ()  


方法作用:文档解析触发此事件

 

public abstractvoid endDocument ()  


方法作用:文档解析结束时触发此事件

 

public abstractvoid startElement (String uri, String localName, String qName, Attributes atts)  


方法作用:当开始读取元素时触发此事件

参数说明:

uri:命名空间

localName:不带命名空间的前缀的标签名

qName:不定期命名空间前缀的标签名

atts:得到所有的属性各和相应的值

 
 

public abstractvoid endElement (String uri, String localName, String qName)  


方法作用:读取的标签结束时触发此事件,参数说明同上

 

 

public abstractvoid characters (char[] ch,int start, int length)  


方法作用:用来处理在XML文件中读到的内容

参数说明:

ch:用于存放文件的内容

start:所读到的字符串在这个数组中的起始位置

length:长度

我们可以用new String(ch,start,length)来获取内容

下面以person.xml文件为例采用SAX解析器来模拟解析这个XML文档:

 
  1. <?xmlversion="1.0"encoding="UTF-8"?> 
  2.  
  3. <persons> 
  4.  
  5.        <personid="23"> 
  6.  
  7.               <name>李明</name> 
  8.  
  9.               <age>30</age> 
  10.  
  11.        </person> 
  12.  
  13.        <personid="20"> 
  14.  
  15.               <name>李向梅</name> 
  16.  
  17.               <age>25</age> 
  18.  
  19.        </person> 
  20.  
  21. </persons> 


解析person.xml触发的事件为:

读到的标签及内容

触发事件

{文档开始}

startDocument()

<persons>

startElement(, "persons", null, "{Attributes}")

"\n\t"

characters("<persons>...</persons>", "12", "2")

<person>

startElement(, "person", null, "{Attributes}")

"\n\t\t"

characters("<persons>...</persons>", "31", "3")

<name>

startElement(, "name", null, "{Attributes}")

"李明"

characters("<persons>...</persons>", "40", "2")

</name>

endElement("", "name", null)

"\n\t\t"

characters("<persons>...</persons>", "50", "3")

<age>

startElement(, "age", null, "{Attributes}")

"30"

characters("<persons>...</persons>", "58", "2")

</age>

endElement("", "age", null)

"\n\t"

characters("<persons>...</persons>", "67", "2")

</person>

endElement("", "person", null)

"\n\t"

characters("<persons>...</persons>", "79", "2")

又重复<person>

….

{文档结束}

endDocument()

实例1:读取XML文件里的内容把这些内容构造成一个Person对象,然后读取这个XML文档里内容将其Person对象添加到一个List集合里:

Person类:

 
  1. public class Person { 
  2.  
  3.   
  4.  
  5.     private Integer id; 
  6.  
  7.     private String name; 
  8.  
  9.     private short age; 
  10.  
  11.      
  12.  
  13.     public Integer getId() { 
  14.  
  15.        return id; 
  16.  
  17.     } 
  18.  
  19.     public void setId(Integer id) { 
  20.  
  21.        this.id = id; 
  22.  
  23.     } 
  24.  
  25.   
  26.  
  27.     public String getName() { 
  28.  
  29.        return name; 
  30.  
  31.     } 
  32.  
  33.     public void setName(String name) { 
  34.  
  35.        this.name = name; 
  36.  
  37.     } 
  38.  
  39.   
  40.  
  41.     public short getAge() { 
  42.  
  43.        return age; 
  44.  
  45.     } 
  46.  
  47.     public void setAge(short age) { 
  48.  
  49.        this.age = age; 
  50.  
  51.     } 
  52.  
  53.   
  54.  
  55.     @Override 
  56.  
  57.     public String toString() { 
  58.  
  59.        return "Person [age=" + age +", id=" + id + ", name=" + name +"]"
  60.  
  61.     } 
  62.  
  63.   
  64.  


业务bean:

 

  1. public class SAXPersonService {  
  2.  
  3. public static List<Person> readXml(InputStream inputStream) 
  4.  
  5.            throws Exception { 
  6.  
  7.   
  8.  
  9.        // 得到一个SAXParserFactory对象 
  10.  
  11.        SAXParserFactory spf = SAXParserFactory.newInstance(); 
  12.  
  13.        // SAX解析对象 
  14.  
  15.        SAXParser saxParser = spf.newSAXParser(); 
  16.  
  17.   
  18.  
  19.        // ContentHandler对象 
  20.  
  21.        XMLContentHandler handler = new XMLContentHandler(); 
  22.  
  23.   
  24.  
  25.        // 开始解析 
  26.  
  27.        saxParser.parse(inputStream, handler); 
  28.  
  29.        // 关闭流 
  30.  
  31.        inputStream.close(); 
  32.  
  33.   
  34.  
  35.        return handler.getPersons(); 
  36.  
  37.   
  38.  
  39.     } 
  40.  


XMLContentHandler继承自DefalutHander而DefaultHandler实现ContentHandler接口

[java] view plain copy print ?
  1. /**
  2. * 继承于DefaultHandler  这个类也是实现ContentHandler
  3. * @author Administrator
  4. *
  5. */ 
  6.  
  7. public class XMLContentHandlerextends DefaultHandler { 
  8.  
  9.   
  10.  
  11.     private List<Person> persons; 
  12.  
  13.     private Person person; 
  14.  
  15.     private String preTag;//当前标记 
  16.  
  17.   
  18.  
  19.     public List<Person> getPersons() { 
  20.  
  21.        return persons; 
  22.  
  23.     } 
  24.  
  25.      
  26.  
  27.     /**
  28.      * 文档开始
  29.      */ 
  30.  
  31.     public void startDocument()throws SAXException { 
  32.  
  33.        persons = new ArrayList<Person>(); 
  34.  
  35.     } 
  36.  
  37.   
  38.  
  39.     /**
  40.      * 读取的文档内容
  41.      */ 
  42.  
  43.     public void characters(char[] ch,int start, int length) 
  44.  
  45.            throws SAXException { 
  46.  
  47.   
  48.  
  49.        if (person != null) { 
  50.  
  51.            String data = new String(ch, start, length); 
  52.  
  53.            // 判断前面的元素是否是"name" 
  54.  
  55.            if ("name".equals(preTag)) { 
  56.  
  57.               person.setName(data); 
  58.  
  59.            } else if ("age".equals(preTag)) { 
  60.  
  61.               person.setAge(new Short(data)); 
  62.  
  63.            } 
  64.  
  65.        } 
  66.  
  67.   
  68.  
  69.     } 
  70.  
  71.      
  72.  
  73.     /**
  74.      * 元素开始
  75.      */ 
  76.  
  77.     public void startElement(String uri, String localName, String qName, 
  78.  
  79.            Attributes attributes) throws SAXException { 
  80.  
  81.        // 判断目前解析到的元素是否等于"person" 
  82.  
  83.        if ("person".equals(localName)) { 
  84.  
  85.            person = new Person(); 
  86.  
  87.            // person.setId(Integer.parseInt(attributes.getValue(0))); 
  88.  
  89.            person.setId(Integer.parseInt(attributes.getValue("","id"))); 
  90.  
  91.        } 
  92.  
  93.        // 当前元素 
  94.  
  95.        preTag = localName; 
  96.  
  97.     } 
  98.  
  99.   
  100.  
  101.     /**
  102.      * 解析完一个元素后就把这个元素加到List里
  103.      */ 
  104.  
  105.     public void endElement(String uri, String localName, String qName) 
  106.  
  107.            throws SAXException { 
  108.  
  109.        if ("person".equals(localName) && person !=null) { 
  110.  
  111.            persons.add(person); 
  112.  
  113.            person = null
  114.  
  115.        } 
  116.  
  117.        //再将这个当前元素设为null 
  118.  
  119.        preTag=null
  120.  
  121.     } 
  122.  


测试:

 
  1. public class SAXPersonServiceTestextends AndroidTestCase { 
  2.  
  3.   
  4.  
  5.     private staticfinal String TAG = "LogTest"
  6.  
  7.     public void testSAXReadXml()throws Exception { 
  8.  
  9.        //从资源文件中获取输入流 
  10.  
  11.        InputStream inputStream = SAXPersonServiceTest.class.getClassLoader() 
  12.  
  13.               .getResourceAsStream("itcast.xml"); 
  14.  
  15.        List<Person> list = SAXPersonService.readXml(inputStream); 
  16.  
  17.        for (Person person : list) { 
  18.  
  19.            System.out.println(person); 
  20.  
  21.        } 
  22.  
  23.     } 
  24.  
  25.  

你可能感兴趣的:(Android开发进阶(五)----------SAX模式解析XML文件)