XmlPullParser解析XML文件

XML解析三种方式

DOM

通用性强,它会将XML文件的所有内容读取到内存中,然后允许您使用DOM API遍历XML树、检索所需的数据;

简单直观,但需要将文档读取到内存,并不太适合移动设备;
SAX

SAX是一个解析速度快并且占用内存少的xml解析器;

采用事件驱动,它并不需要解析整个文档;

实现:继承DefaultHandler,覆写startElement、endElement、characters等方法;

PULL

Android自带的XML解析器,和SAX基本类似,也是事件驱动,不同的是PULL事件返回的是数值型;推荐使用。


PULL解析XML核心代码

[java]  view plain  copy
  1. XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
  2. XmlPullParser parser=factory.newPullParser();  
  3. parser.setInput(fileInputStream, “utf-8”);//设置数据源编码  
  4. int eventCode = parser.getEventType();//获取事件类型  
  5. while(eventCode != XmlPullParser.END_DOCUMENT)  {     
  6.     switch (eventCode){     
  7.         case XmlPullParser.START_DOCUMENT: //开始读取XML文档    
  8.         //实例化集合类    
  9.         break;     
  10.     case XmlPullParser.START_TAG://开始读取某个标签       
  11.         if("person".equals(parser.getName())) {     
  12.         //通过getName判断读到哪个标签,然后通过nextText()获取文本节点值,或通过getAttributeValue(i)获取属性节点值  
  13.         }     
  14.         break;  
  15.     case XmlPullParser.END_TAG://读完一个Person,可以将其添加到集合类中  
  16.         break;  
  17.     }  
  18.     parser.next();  
  19. }  

PULL解析XML示例方法


Java方法
[java]  view plain  copy
  1. public static List<Person> readXML(InputStream inStream) {  
  2.     XmlPullParser parser = Xml.newPullParser();  
  3.     try {  
  4.         parser.setInput(inStream, "UTF-8");// 设置数据源编码  
  5.         int eventType = parser.getEventType();// 获取事件类型  
  6.         Person currentPerson = null;  
  7.         List<Person> persons = null;  
  8.         while (eventType != XmlPullParser.END_DOCUMENT) {  
  9.             switch (eventType) {  
  10.             case XmlPullParser.START_DOCUMENT:// 文档开始事件,可以进行数据初始化处理  
  11.                 persons = new ArrayList<Person>();// 实例化集合类  
  12.                 break;  
  13.             case XmlPullParser.START_TAG://开始读取某个标签  
  14.                 //通过getName判断读到哪个标签,然后通过nextText()获取文本节点值,或通过getAttributeValue(i)获取属性节点值  
  15.                 String name = parser.getName();  
  16.                 if (name.equalsIgnoreCase("person")) {  
  17.                     currentPerson = new Person();  
  18.                     currentPerson.setId(new Integer(parser.getAttributeValue(null"id")));  
  19.                 } else if (currentPerson != null) {  
  20.                     if (name.equalsIgnoreCase("name")) {  
  21.                         currentPerson.setName(parser.nextText());// 如果后面是Text元素,即返回它的值  
  22.                     } else if (name.equalsIgnoreCase("age")) {  
  23.                         currentPerson.setAge(new Short(parser.nextText()));  
  24.                     }  
  25.                 }  
  26.                 break;  
  27.             case XmlPullParser.END_TAG:// 结束元素事件  
  28.                 //读完一个Person,可以将其添加到集合类中  
  29.                 if (parser.getName().equalsIgnoreCase("person")&& currentPerson != null) {  
  30.                     persons.add(currentPerson);  
  31.                     currentPerson = null;  
  32.                 }  
  33.                 break;  
  34.             }  
  35.             eventType = parser.next();  
  36.         }  
  37.         inStream.close();  
  38.         return persons;  
  39.     } catch (Exception e) {  
  40.         e.printStackTrace();  
  41.     }  
  42.     return null;  
  43. }  


应用

XML文件
[html]  view plain  copy
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <persons>  
  3.     <person id="23">  
  4.         <name>孙洋洋</name>  
  5.         <age>30</age>  
  6.     </person>  
  7.     <person id="20">  
  8.         <name>孙彬彬</name>  
  9.         <age>25</age>  
  10.     </person>  
  11. </persons>  

Activity文件
[java]  view plain  copy
  1. package com.app.data;  
  2.   
  3. import java.io.BufferedWriter;  
  4. import java.io.File;  
  5. import java.io.FileInputStream;  
  6. import java.io.FileNotFoundException;  
  7. import java.io.FileOutputStream;  
  8. import java.io.InputStream;  
  9. import java.io.OutputStreamWriter;  
  10. import java.net.HttpURLConnection;  
  11. import java.net.URL;  
  12. import java.util.ArrayList;  
  13. import java.util.HashMap;  
  14. import java.util.List;  
  15.   
  16. import org.xmlpull.v1.XmlPullParser;  
  17. import org.xmlpull.v1.XmlPullParserException;  
  18. import org.xmlpull.v1.XmlPullParserFactory;  
  19.   
  20. import com.app.other.Person;  
  21.   
  22. import android.app.Activity;  
  23. import android.os.Bundle;  
  24. import android.util.Xml;  
  25. import android.widget.TextView;  
  26.   
  27. public class XMLActivity extends Activity {  
  28.     @Override  
  29.     protected void onCreate(Bundle savedInstanceState) {  
  30.         // TODO Auto-generated method stub  
  31.         super.onCreate(savedInstanceState);  
  32.         setContentView(R.layout.activity_xml);  
  33.           
  34.         StringBuilder sBuilder = new StringBuilder();  
  35.         File xmlFile = new File("/mnt/sdcard/App/person.xml");  
  36.         try {  
  37.             FileInputStream inputStream = new FileInputStream(xmlFile);  
  38. //          URL url = new URL("http://10.0.2.2:8888/android/person.xml");  
  39. //          HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();  
  40. //          InputStream inputStream = urlConnection.getInputStream();  
  41.             List<Person> list = readXML(inputStream);  
  42.             for (int i = 0; i < list.size(); i++) {  
  43.                 Person person = list.get(i);  
  44.                 sBuilder.append("第-" + i + "-条记录:\n");  
  45.                 sBuilder.append("getName--" + person.getName() + "\n");  
  46.                 sBuilder.append("getAge--" + person.getAge() + "\n");  
  47.                 sBuilder.append("getId--" + person.getId() + "\n");  
  48.             }  
  49.             inputStream.close();  
  50.         } catch (Exception e) {  
  51.             // TODO Auto-generated catch block  
  52.             e.printStackTrace();  
  53.         }  
  54.         TextView textView = (TextView)findViewById(R.id.textView2);  
  55.         textView.setText(sBuilder);  
  56.     }  
  57.   
  58.     public static List<Person> readXML(InputStream inStream) {  
  59.         XmlPullParser parser = Xml.newPullParser();  
  60.         try {  
  61.             parser.setInput(inStream, "UTF-8");// 设置数据源编码  
  62.             int eventType = parser.getEventType();// 获取事件类型  
  63.             Person currentPerson = null;  
  64.             List<Person> persons = null;  
  65.             while (eventType != XmlPullParser.END_DOCUMENT) {  
  66.                 switch (eventType) {  
  67.                 case XmlPullParser.START_DOCUMENT:// 文档开始事件,可以进行数据初始化处理  
  68.                     persons = new ArrayList<Person>();// 实例化集合类  
  69.                     break;  
  70.                 case XmlPullParser.START_TAG://开始读取某个标签  
  71.                     //通过getName判断读到哪个标签,然后通过nextText()获取文本节点值,或通过getAttributeValue(i)获取属性节点值  
  72.                     String name = parser.getName();  
  73.                     if (name.equalsIgnoreCase("person")) {  
  74.                         currentPerson = new Person();  
  75.                         currentPerson.setId(new Integer(parser.getAttributeValue(null"id")));  
  76.                     } else if (currentPerson != null) {  
  77.                         if (name.equalsIgnoreCase("name")) {  
  78.                             currentPerson.setName(parser.nextText());// 如果后面是Text元素,即返回它的值  
  79.                         } else if (name.equalsIgnoreCase("age")) {  
  80.                             currentPerson.setAge(new Short(parser.nextText()));  
  81.                         }  
  82.                     }  
  83.                     break;  
  84.                 case XmlPullParser.END_TAG:// 结束元素事件  
  85.                     //读完一个Person,可以将其添加到集合类中  
  86.                     if (parser.getName().equalsIgnoreCase("person")&& currentPerson != null) {  
  87.                         persons.add(currentPerson);  
  88.                         currentPerson = null;  
  89.                     }  
  90.                     break;  
  91.                 }  
  92.                 eventType = parser.next();  
  93.             }  
  94.             inStream.close();  
  95.             return persons;  
  96.         } catch (Exception e) {  
  97.             e.printStackTrace();  
  98.         }  
  99.         return null;  
  100.     }  
  101. }  

XML布局文件
[html]  view plain  copy
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="match_parent"  
  5.     android:orientation="vertical"  
  6.     android:padding="15dp" >  
  7.   
  8.     <TextView  
  9.         android:id="@+id/textView1"  
  10.         android:layout_width="wrap_content"  
  11.         android:layout_height="wrap_content"  
  12.         android:text="XML文件读取"  
  13.         android:layout_gravity="center_horizontal" />  
  14.   
  15.     <TextView  
  16.         android:id="@+id/textView2"  
  17.         android:layout_width="wrap_content"  
  18.         android:layout_height="wrap_content"  
  19.         android:text="TextView" />  
  20.   
  21. </LinearLayout>  

XML文件位置



执行结果:




===================================================================================================================
===================================== 另一篇文章 =================================================================

android xml 的解析.

1.普通型

Xml代码   收藏代码
  1. <?xml version=”1.0″ ?>  
  2. <statuses>  
  3. <status>  
  4. <source1>a</source1>  
  5. <source2>a</source2>  
  6. <source2>a</source2>  
  7. </status>  
  8. <statuses>  
  9. </xml>  
 
解析代码.
Java代码   收藏代码
  1. try{  
  2. xpp.setInput( new StringReader ( “xml string” ) );  
  3. XmlPullParser parser = XmlPullParserFactory.newInstance()  
  4. .newPullParser();  
  5. int eventType = parser.getEventType();  
  6. while (eventType != XmlPullParser.END_DOCUMENT) {  
  7. if (eventType == XmlPullParser.START_TAG) {  
  8. String name = parser.getName();  
  9. Log.v(“tag”,parser.getName()+”=”+parser.next());  
  10. }  
  11. eventType = parser.next();  
  12. }  
  13. catch (XmlPullParserException e) {  
  14. catch (Exception e) {  
  15. }  
 
2.嵌套子类.
Xml代码   收藏代码
  1. <?xml version=”1.0″ encoding=”UTF-8″ standalone=”no”?>  
  2. <statuses>  
  3. <status>  
  4.  <source1>a</source1>  
  5.  <source2>a</source2>  
  6.  <source2>a</source2>  
  7.  <user>  
  8.    <source1>a</source1>  
  9.    <source2>a</source2>  
  10.    <source2>a</source2>  
  11.  </user>  
  12. </status>  
  13. <status>  
  14.  <source1>a</source1>  
  15.  <source2>a</source2>  
  16.  <source2>a</source2>  
  17.  <user>  
  18.    <source1>a</source1>  
  19.    <source2>a</source2>  
  20.    <source2>a</source2>  
  21.  </user>  
  22. </status>  
  23. <statuses>  
  24. </xml>  
 
解析代码:
Java代码   收藏代码
  1. try{  
  2. XmlPullParser parser = XmlPullParserFactory.newInstance()  
  3. .newPullParser();  
  4.  xpp.setInput( new StringReader ( xml string ) );  
  5. parser.next();  
  6. parser.require(XmlPullParser.START_TAG, null, “statuses”);  
  7. while (parser.nextTag() != XmlPullParser.END_TAG) {  
  8. parser.require(XmlPullParser.START_TAG, null, “status”);  
  9. for (int i=0;i<3;i++){  
  10. parser.nextTag();  
  11. Log.v(“tag”,parser.getName()+”=”+ parser.nextText());  
  12. }  
  13. while (parser.nextTag() != XmlPullParser.END_TAG) {  
  14. parser.require(XmlPullParser.START_TAG, null, “user”);  
  15. while (parser.nextTag() != XmlPullParser.END_TAG) {  
  16. String name = parser.getName();  
  17. String text2 = parser.nextText();  
  18. Log.v(“tag”,”text2″+text2);  
  19. parser.require(XmlPullParser.END_TAG, null, name);  
  20. }  
  21. parser.require(XmlPullParser.END_TAG, null, “user”);  
  22. }  
  23. parser.require(XmlPullParser.END_TAG, null, “status”);  
  24. }  
  25. parser.require(XmlPullParser.END_TAG, null, “statuses”);  
  26. parser.next();  
  27. parser.require(XmlPullParser.END_DOCUMENT, nullnull);  
  28. // global.userinfo.dump();  
  29. catch (XmlPullParserException e) {  
  30. catch (Exception e) {  
  31. }  
 
最里面那个可以满足 <user>也是循环. 如果<user>不循环.
可以使用.
Java代码   收藏代码
  1. for (int i=0;i<3;i++){  
  2. parser.nextTag();  
  3. Log.v(“tag”,parser.getName()+”=”+ parser.nextText());  
  4. }  
 
代替.

开发过程中遇到 XmlPullParser.netText()方法造成的Bug
解决如下:

在Android上使用XmlPullParser是一中高效率和易维护解析XML的方法 。Android已经在历史上有两个实现这个接口实现类:

实现Xml.newPullParser()调用nextText()有个错误,nextText()并不总是向文档中所提到优先于END_TAG执行 。

因此,一些应用可能会出现bug在额外调用next()或nextTag();

[html]  view plain copy
  1.     throws XmlPullParserException, IOException {  
  2.     XmlPullParser parser = Xml.newPullParser();  
  3.     parser.setInput(reader);  
  4.   
  5.     parser.nextTag();  
  6.     parser.require(XmlPullParser.START_TAG, null, "menu");  
  7.     while (parser.nextTag() == XmlPullParser.START_TAG) {  
  8.         parser.require(XmlPullParser.START_TAG, null, "item");  
  9.         String itemText = parser.nextText();  
  10.         parser.nextTag(); // this call shouldn’t be necessary!  
  11.         parser.require(XmlPullParser.END_TAG, null, "item");  
  12.         System.out.println("menu option: " + itemText);  
  13.     }  
  14.     parser.require(XmlPullParser.END_TAG, null, "menu");  
  15. }  
  16.   
  17. public static void main(String[] args) throws Exception {  
  18.     new Menu().parseXml(new StringReader("<?xml version='1.0'?>"  
  19.             + "<menu>"  
  20.             + "  <item>Waffles</item>"  
  21.             + "  <item>Coffee</item>"  
  22.             + "</menu>"));  
  23. }  
在android4.0中,改变了Xml.newPullParser()返回KxmlParser类,同时删除了ExpatPullParser类。这样就修正了 nextTag()的bug.

不幸的是,当前可能会崩溃的应用程序都是低于android4.0版本的,下面是错误信息。

[html]  view plain copy
  1. org.xmlpull.v1.XmlPullParserException: expected: END_TAG {null}item (position:START_TAG <item>@1:37 in java.io.StringReader@40442fa8)   
  2.      at org.kxml2.io.KXmlParser.require(KXmlParser.java:2046)  
  3.      at com.publicobject.waffles.Menu.parseXml(Menu.java:25)  
  4.  at com.publicobject.waffles.Menu.main(Menu.java:32)  
解决的办法是只有在调用 nextText()之后再跳用 nextTag(),仅当当前的位置不是 END_TAG。
[html]  view plain copy
  1. while (parser.nextTag() == XmlPullParser.START_TAG) {  
  2.      parser.require(XmlPullParser.START_TAG, null, "item");  
  3.      String itemText = parser.nextText();  
  4.      if (parser.getEventType() != XmlPullParser.END_TAG) {  
  5.          parser.nextTag();  
  6.      }  
  7.      parser.require(XmlPullParser.END_TAG, null, "item");  
  8.      System.out.println("menu option: " + itemText);  
  9.  }  
上面的代码可以正确解析所有xml版本,如果应用程序广范的使用了 nextText(),那就在使用 nextText()的地方用下面的辅助方法。
[html]  view plain copy
  1. private String safeNextText(XmlPullParser parser)  
  2.          throws XmlPullParserException, IOException {  
  3.      String result = parser.nextText();  
  4.      if (parser.getEventType() != XmlPullParser.END_TAG) {  
  5.          parser.nextTag();  
  6.      }  
  7.      return result;  
  8.  }  
使用单一的XmlPullParse简化了我们的维护,同时可以让我们有更多的精力花费在调高系统的性能。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值