On AndroidUsing XmlPullParser is a highly efficient and easy-to-maintain method for parsing XML. Android has historically had two implementation classes that implement this interface:
KXmlParser, via XmlPullParserFactory.newPullParser().
ExpatPullParser, via Xml.newPullParser().
ImplementationXml.newPullParser()
Calling<span style="color:#007000">nextText()</span><span style="background-color:rgb(255,255,255)">There is an error,<span style="color:rgb(0,112,0); font-family:monospace; line-height:12px">nextText() </span></span>
does not always take precedence over END_TAG as mentioned in the documentation
.
Therefore, some applications may have bugs in additional calls to next() or nextTag();
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>")); }
In android4.0, the Xml has been changed .newPullParser() returns the KxmlParser class and deletes the ExpatPullParser class. This fixes the nextTag() bug.
Unfortunately, the current applications that may crash are all versions lower than android 4.0. The following is the error message.
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)
The solution is to only use nextTag()## after calling nextText() #, only if the current position is not END_TAG.
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); }
nextText() extensively, then use nextText( ) use the following auxiliary method.
private String safeNextText(XmlPullParser parser) throws XmlPullParserException, IOException { String result = parser.nextText(); if (parser.getEventType() != XmlPullParser.END_TAG) { parser.nextTag(); } return result; }