SAX解析Xml文档 以及SAX解析方法的优缺点
写此文章只为,以后用到后可以方便查看,经此而已:
SAX解析方法的原理:SAX解析XML文件采用事件驱动的方式进行。也就是对文档进行顺序扫描,当扫描到文档(document)开始与结束,元素(Element)开始与结束、文档(document)结束等地方时通知事件处理的函数。 事件处理函数做相应的动作,然后继续同样的扫描,直到文档结束。
SAX解析Xml文件的优点和缺点:
SAX解析的优点:(1)解析速度快 .(2)解析过程中是一种一边解析一边执行的过程。 (3) ContentHandler 对象可以注册多个 (4)内存消耗比较少
SAX 解析的缺点: (1)不能够修改文档 (2)不能随机访问,SAX解析器对文档的解析式顺序进行的无法做到向文档中添加节点,更不能删除和修改文档中的内容
SAX解析Xml文档的时候需要继承DefaultHandler这个,实现我们需要的方法:
void starDocument(); //文档开始执行的方法
void endDocument(); //文档结束时候执行的方法
void startElement(String uri,String localName,String qName,Attribute attr); //标签开始解析时候执行
void endElement(String uri,String localName,String qName,Attribute attr ); //标签结束解析的时候执行
void characters(char[] ch,int start,int length); //解析标签属性时执行的方法
userInfo.xml 文件
<?xml version="1.0" encoding="UTF-8"?>
<persons>
<person id="2">
<name>哈哈</name>
<age>22</age>
</person>
<person id="23">
<name>呵呵</name>
<age>28</age>
</person>
<person id="24">
<name>嘻嘻</name>
<age>22</age>
</person>
<person id="25">
<name>呵呵</name>
<age>29</age>
</person>
</persons>
继承DefaultHandler类的方法,实现主要解析的方法:
1 import java.io.IOException; 2 import java.net.ContentHandler; 3 import java.net.URLConnection; 4 import java.util.ArrayList; 5 import java.util.List; 6 7 import org.xml.sax.Attributes; 8 import org.xml.sax.SAXException; 9 import org.xml.sax.helpers.DefaultHandler; 10 11 import android.util.Log; 12 13 public class SAXforHandler extends DefaultHandler { 14 private static final String TAG = "SAXforHandler"; 15 /** 16 * 用来存放解析的UserInfo对象 17 */ 18 private List<UserInfo> list = null; 19 /** 20 * UserInfo 对象的引用,记录当前的UserInfo 21 */ 22 private UserInfo userInfo = null; 23 /** 24 * 通过此变量,记录当前一个标签的名称 25 */ 26 private String tag; 27 28 public void startDocument() throws SAXException { // 文档开始执行的放法 29 super.startDocument(); 30 list = new ArrayList<UserInfo>(); 31 Log.i(TAG, "**************startDocument()******************"); 32 33 } 34 35 public void endDocument() throws SAXException { // 文档解析结束时候执行的方法 36 super.endDocument(); 37 Log.i(TAG, "**************endDocument()******************"); 38 } 39 40 /** 41 * uri 是命名空间 localName 标签的名称 : 如name age等 qName 带命名空间的标签名 Attributes 42 * 存放该标签的所有属性 如<person id=2> 中的id就为属性 43 * 44 * 当localName为person的时候,我们拿出 45 * person标签的属性值,只有一个属性,也可以直接person.setId(Integer.valueOf 46 * (attributes.getValue(0))); 然后设置tag=person 47 * ,当这个方法执行完了,然后会执行回调方法characters(char[] ch,int start,int length),这是一个循环的过程 48 * 49 * 50 */ 51 public void startElement(String uri, String localName, String qName, 52 Attributes attributes) throws SAXException { // 标签解析开始时候执行的方法 53 super.startElement(uri, localName, qName, attributes); 54 55 if("person".equals(localName)){ 56 for(int i=0;i<attributes.getLength();i++){ 57 Log.i(TAG, "Attributes:"+attributes.getLength()+"+attributesValues:"+attributes.getValue(i)); 58 userInfo=new UserInfo(); 59 userInfo.setId(Integer.valueOf(attributes.getValue(i))); 60 } 61 } 62 63 tag=localName; 64 Log.i(TAG, "localName="+localName); 65 66 } 67 /** 68 * uri 命名空间 69 * localName 标签的名称,如name,age 等 70 * qName 带命名空间的标签名、 71 * localName=person 并且person不等于null ,说明一个person对象解析完毕 72 * 将userInfo加入到list集合中 73 * 每个标签解析完了需要将tag=null 74 */ 75 public void endElement(String uri, String localName, String qName) 76 throws SAXException { // 标签解析结束时候执行的方法 77 super.endElement(uri, localName, qName); 78 if("person".equals(localName) && userInfo!=null){ 79 list.add(userInfo); 80 userInfo=null; 81 } 82 tag=null; 83 84 } 85 /** 86 * 这个方法只要是获取两个标签里面的值的,这里最好用trim() 方法过滤,可以避免读取到的xml有空格带来不必要的麻烦 87 * 执行完这个方法就执行回调方法endElement(String uri,String localName,String qName),这也是一个循环的过程 88 */ 89 public void characters(char[] ch, int start, int length) 90 throws SAXException { // 解析标签属性执行的方法 91 super.characters(ch, start, length); 92 String date=new String(ch, start, length).trim(); 93 if(!"".equals(date)){ 94 Log.i(TAG, "Content:"+date); 95 } 96 if("name".equals(tag)){ 97 userInfo.setName(date); 98 }else if("age".equals(tag)){ 99 userInfo.setAge(Integer.valueOf(date)); 100 } 101 102 } 103 104 /** 105 * 拿到成员变量List<UserInfo> list的方法 106 */ 107 public List<UserInfo> getPList(){ 108 return list; 109 } 110 }
测试类:
1 import java.io.InputStream; 2 import java.util.List; 3 4 import javax.xml.parsers.SAXParser; 5 import javax.xml.parsers.SAXParserFactory; 6 7 import android.os.Bundle; 8 import android.app.Activity; 9 import android.view.Menu; 10 import android.widget.TextView; 11 12 public class MainActivity extends Activity { 13 14 private TextView tv; 15 protected void onCreate(Bundle savedInstanceState) { 16 super.onCreate(savedInstanceState); 17 setContentView(R.layout.activity_main); 18 tv=(TextView) findViewById(R.id.action_settings); 19 try{ 20 InputStream is=getAssets().open("persons.xml"); //打开这个Xml文件 21 22 SAXforHandler saXforHandler=new SAXforHandler(); //new 一个这个类的对象 23 SAXParserFactory sPF=SAXParserFactory.newInstance(); 24 SAXParser saxParser=sPF.newSAXParser(); 25 //直接用XMLParser 26 saxParser.parse(is, saXforHandler); 27 List<UserInfo > list=saXforHandler.getPList(); 28 is.close(); 29 30 String user=null; 31 for (UserInfo userInfo : list) { 32 user+="id="+userInfo.getId()+"\n"+"dd="+userInfo.getDd()+"\n"+"name="+userInfo.getName()+"\n"+"age="+userInfo.getAge(); 33 } 34 35 36 tv.setText(user+""); 37 38 }catch(Exception e){ 39 e.printStackTrace(); 40 } 41 42 } 43 44 45 46 }

浙公网安备 33010602011771号