您的位置:首页 > 移动开发 > Android开发

android xml解析 XmlPullParser的使用

2014-04-17 16:14 471 查看
本文转自:http://samwong.iteye.com/blog/1000403

android xml 的解析.

1.普通型

Xml代码



<?xml version=”1.0″ ?>

<statuses>

<status>

<source1>a</source1>

<source2>a</source2>

<source2>a</source2>

</status>

<statuses>

</xml>

解析代码.

Java代码



try{

xpp.setInput( new StringReader ( “xml string” ) );

XmlPullParser parser = XmlPullParserFactory.newInstance()

.newPullParser();

int eventType = parser.getEventType();

while (eventType != XmlPullParser.END_DOCUMENT) {

if (eventType == XmlPullParser.START_TAG) {

String name = parser.getName();

Log.v(“tag”,parser.getName()+”=”+parser.next());

}

eventType = parser.next();

}

} catch (XmlPullParserException e) {

} catch (Exception e) {

}

2.嵌套子类.

Xml代码



<?xml version=”1.0″ encoding=”UTF-8″ standalone=”no”?>

<statuses>

<status>

<source1>a</source1>

<source2>a</source2>

<source2>a</source2>

<user>

<source1>a</source1>

<source2>a</source2>

<source2>a</source2>

</user>

</status>

<status>

<source1>a</source1>

<source2>a</source2>

<source2>a</source2>

<user>

<source1>a</source1>

<source2>a</source2>

<source2>a</source2>

</user>

</status>

<statuses>

</xml>

解析代码:

Java代码



try{

XmlPullParser parser = XmlPullParserFactory.newInstance()

.newPullParser();

xpp.setInput( new StringReader ( xml string ) );

parser.next();

parser.require(XmlPullParser.START_TAG, null, “statuses”);

while (parser.nextTag() != XmlPullParser.END_TAG) {

parser.require(XmlPullParser.START_TAG, null, “status”);

for (int i=0;i<3;i++){

parser.nextTag();

Log.v(“tag”,parser.getName()+”=”+ parser.nextText());

}

while (parser.nextTag() != XmlPullParser.END_TAG) {

parser.require(XmlPullParser.START_TAG, null, “user”);

while (parser.nextTag() != XmlPullParser.END_TAG) {

String name = parser.getName();

String text2 = parser.nextText();

Log.v(“tag”,”text2″+text2);

parser.require(XmlPullParser.END_TAG, null, name);

}

parser.require(XmlPullParser.END_TAG, null, “user”);

}

parser.require(XmlPullParser.END_TAG, null, “status”);

}

parser.require(XmlPullParser.END_TAG, null, “statuses”);

parser.next();

parser.require(XmlPullParser.END_DOCUMENT, null, null);

// global.userinfo.dump();

} catch (XmlPullParserException e) {

} catch (Exception e) {

}

最里面那个可以满足 <user>也是循环. 如果<user>不循环.

可以使用.

Java代码



for (int i=0;i<3;i++){

parser.nextTag();

Log.v(“tag”,parser.getName()+”=”+ parser.nextText());

}

代替.

开发过程中遇到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

throws XmlPullParserException, IOException {

XmlPullParser parser = Xml.newPullParser();

parser.setInput(reader);

parser.nextTag();

parser.require(XmlPullParser.START_TAG, null, "menu");

while (parser.nextTag() == XmlPullParser.START_TAG) {

parser.require(XmlPullParser.START_TAG, null, "item");

String itemText = parser.nextText();

parser.nextTag(); // this call shouldn’t be necessary!

parser.require(XmlPullParser.END_TAG, null, "item");

System.out.println("menu option: " + itemText);

}

parser.require(XmlPullParser.END_TAG, null, "menu");

}

public static void main(String[] args) throws Exception {

new Menu().parseXml(new StringReader("<?xml version='1.0'?>"

+ "<menu>"

+ " <item>Waffles</item>"

+ " <item>Coffee</item>"

+ "</menu>"));

}

在android4.0中,改变了Xml.newPullParser()返回KxmlParser类,同时删除了ExpatPullParser类。这样就修正了nextTag()的bug.

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

[html] view
plaincopy

org.xmlpull.v1.XmlPullParserException: expected: END_TAG {null}item (position:START_TAG <item>@1:37 in java.io.StringReader@40442fa8)

at org.kxml2.io.KXmlParser.require(KXmlParser.java:2046)

at com.publicobject.waffles.Menu.parseXml(Menu.java:25)

at com.publicobject.waffles.Menu.main(Menu.java:32)

解决的办法是只有在调用nextText()之后再跳用nextTag(),仅当当前的位置不是END_TAG。

[html] view
plaincopy

while (parser.nextTag() == XmlPullParser.START_TAG) {

parser.require(XmlPullParser.START_TAG, null, "item");

String itemText = parser.nextText();

if (parser.getEventType() != XmlPullParser.END_TAG) {

parser.nextTag();

}

parser.require(XmlPullParser.END_TAG, null, "item");

System.out.println("menu option: " + itemText);

}

上面的代码可以正确解析所有xml版本,如果应用程序广范的使用了nextText(),那就在使用nextText()的地方用下面的辅助方法。

[html] view
plaincopy

private String safeNextText(XmlPullParser parser)

throws XmlPullParserException, IOException {

String result = parser.nextText();

if (parser.getEventType() != XmlPullParser.END_TAG) {

parser.nextTag();

}

return result;

}

使用单一的XmlPullParse简化了我们的维护,同时可以让我们有更多的精力花费在调高系统的性能。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: