解析XML文件之使用SAM解析器

来源:互联网 发布:美服lol免费加速器知乎 编辑:程序博客网 时间:2024/06/10 06:10

http://blog.csdn.net/zhaokaiqiang1992/article/details/28142951


解析XML文件之使用SAM解析器

标签: xmlsax解析器解析
 1286人阅读 评论(0) 收藏 举报
 分类:

XML是一种常见的数据传输方式,所以在开发中,我们会遇到对XML文件进行解析的时候,本篇主要介绍使用SAM解析器,对XML文件进行解析。

SAX解析器的优点是显而易见的,那就是SAX并不需要将所有的文档都加载内存之后才进行解析,SAX是事件驱动机制的,也就是碰到元素节点、文本节点、文档节点的时候,都会触发一定的事件,我们只需要在相应的回调事件里面进行相应的处理就可以了。因为这个特点,所以SAX解析占用的内存比较少,其他的解析方式,比如下一节要介绍的DOM解析器,则占用内存比较多。在解析比较小的XML文件的时候,区别不是很大,大家哪种顺手就可以用哪种。但是当需要解析的文档达到几百K以上的时候,还是推荐使用SAX解析器或者是PULL解析器。这几种XML的解析方式,我都会在以后的文章中进行介绍,今天重点看SAX解析器。

下面是我们要进行解析的文件格式

[html] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <persons>  
  3.     <person id="23">  
  4.         <name>liming</name>  
  5.         <age>30</age>  
  6.     </person>  
  7.     <person id="20">  
  8.         <name>lixiangmei</name>  
  9.         <age>25</age>  
  10.     </person>  
  11. </persons>  

下面是我们的实体类

[java] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. public class Person {  
  2.     private Integer id;  
  3.     private String name;  
  4.     private Short age;  
  5.       
  6.     public Person(){}  
  7.       
  8.     public Person(Integer id, String name, Short age) {  
  9.         this.id = id;  
  10.         this.name = name;  
  11.         this.age = age;  
  12.     }  
  13.       
  14.     public Integer getId() {  
  15.         return id;  
  16.     }  
  17.     public void setId(Integer id) {  
  18.         this.id = id;  
  19.     }  
  20.     public String getName() {  
  21.         return name;  
  22.     }  
  23.     public void setName(String name) {  
  24.         this.name = name;  
  25.     }  
  26.     public Short getAge() {  
  27.         return age;  
  28.     }  
  29.     public void setAge(Short age) {  
  30.         this.age = age;  
  31.     }  
  32.     @Override  
  33.     public String toString() {  
  34.         return "Person [age=" + age + ", id=" + id + ", name=" + name + "]";  
  35.     }  
  36.       
  37. }  

我们定义一个SAM解析器,对内容进行解析

[java] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. /** 
  2.  * 使用SAX对XML文件进行解析 
  3.  *  
  4.  * @author zhaokaiqiang 
  5.  *  
  6.  */  
  7. public class SaxResolve {  
  8.   
  9.     public List<Person> getPersons(InputStream inputStream) throws Exception {  
  10.   
  11.         //获取SAXParser对象  
  12.         SAXParser parser = SAXParserFactory.newInstance().newSAXParser();  
  13.         //实例化我们的解析器  
  14.         PersonHandler handler = new PersonHandler();  
  15.         //开始对输入流解析  
  16.         parser.parse(inputStream, handler);  
  17.         //关闭输入流  
  18.         inputStream.close();  
  19.         //返回结果  
  20.         return handler.getPersons();  
  21.     }  
  22.   
  23.     private class PersonHandler extends DefaultHandler {  
  24.   
  25.         private List<Person> persons;  
  26.         private Person person = null;  
  27.         private String tag = null;  
  28.   
  29.         public List<Person> getPersons() {  
  30.             return persons;  
  31.         }  
  32.   
  33.         // 当读取到xml文件的开始部分时,对persons进行初始化  
  34.         @Override  
  35.         public void startDocument() throws SAXException {  
  36.             persons = new ArrayList<Person>();  
  37.         }  
  38.   
  39.         // 这个方法对元素节点进行解析,如我们数据中的<person>、<age>、<name>都属于元素节点  
  40.         // 当读取到person节点时,对Person对象进行初始化,同时获取到属性节点的值,并赋值给id,  
  41.         // 记录现在的节点的名称,即localName,用于Person节点内部节点的解析  
  42.         @Override  
  43.         public void startElement(String uri, String localName, String qName,  
  44.                 Attributes attributes) throws SAXException {  
  45.             if (localName.equals("person")) {  
  46.                 person = new Person();  
  47.                 person.setId(new Integer(attributes.getValue(0)));  
  48.             }  
  49.             tag = localName;  
  50.         }  
  51.   
  52.         // 这个回调方法用于对文本节点进行解析,如<age>30</age>里面的30就是属于文本节点,  
  53.         // 我们根据元素节点tag的取值,取出里面的文本节点,然后对person进行赋值  
  54.         @Override  
  55.         public void characters(char[] ch, int start, int length)  
  56.                 throws SAXException {  
  57.   
  58.             if (tag != null) {  
  59.                 String data = new String(ch, start, length);  
  60.                 if ("name".equals(tag)) {  
  61.                     person.setName(data);  
  62.                 } else if ("age".equals(tag)) {  
  63.                     person.setAge(new Short(data));  
  64.                 }  
  65.             }  
  66.   
  67.         }  
  68.   
  69.         /* 
  70.          * 当到达一个元素节点的结束时 比如  
  71.          * <person id="20">  
  72.          *  <name>lixiangmei</name> 
  73.          *  <age>25</age>  
  74.          * </person> 
  75.          * 当到达这里的</person>节点,就会出发下面的事件,我们在这个回调方法里面将解析出的person对象 
  76.          * 添加到persons里面,并且将person和tag进行初始化,进行下一个person节点的解析 
  77.          */  
  78.         @Override  
  79.         public void endElement(String uri, String localName, String qName)  
  80.                 throws SAXException {  
  81.             if (localName.equals("person")) {  
  82.                 persons.add(person);  
  83.                 person = null;  
  84.             }  
  85.             tag = null;  
  86.         }  
  87.   
  88.     }  
  89.   
  90. }  

因为注释比较详细,所以不过多解析,下面我们使用单元测试,对解析进行测试

[java] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. //测试SAX解析  
  2.     public void testSax() throws Exception {  
  3.         //从xml文件中获取输入流  
  4.         InputStream inputStream = getClass().getClassLoader()  
  5.                 .getResourceAsStream("persons.xml");  
  6.         //获取解析出的对象  
  7.         List<Person> persons = new SaxResolve().getPersons(inputStream);  
  8.         //打印  
  9.         for (Person p : persons) {  
  10.             Log.d(TAG, p.toString());  
  11.         }  
  12.   
  13.     }  

下面是解析结果



0 0
原创粉丝点击