android xml解析 XmlPullParser的使用

来源:互联网 发布:土地证打印软件 编辑:程序博客网 时间:2024/05/31 18:57

本文转自:http://samwong.iteye.com/blog/1000403

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已经在历史上有两个实现这个接口实现类:

  • KXmlParser,通过XmlPullParserFactory.newPullParser() 。

  • ExpatPullParser,通过Xml.newPullParser() 。

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

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

[html] view plaincopy
  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 plaincopy
  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 plaincopy
  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 plaincopy
  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简化了我们的维护,同时可以让我们有更多的精力花费在调高系统的性能。
0 0