Be careful with the XmlPullParser.netText() method

黄舟
Release: 2017-02-09 13:58:14
Original
1670 people have browsed it

Using XmlPullParser on Android is a highly efficient and easy-to-maintain method of parsing XML. Android has historically had two implementation classes that implement this interface:

  • KXmlParser, via XmlPullParserFactory.newPullParser().

  • ExpatPullParser, via Xml.newPullParser().

There is a bug in the implementation of Xml.newPullParser() calling nextText(), nextText() is not always executed prior to 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=&#39;1.0&#39;?>"  
            + "<menu>"  
            + "  <item>Waffles</item>"  
            + "  <item>Coffee</item>"  
            + "</menu>"));  
}
Copy after login

In android 4.0, Xml.newPullParser() has been changed to return the KxmlParser class, and at the same time Removed 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)
Copy after login

The solution is to jump to nextTag() only after calling nextText(), only when 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);  
 }
Copy after login

The above code can correctly parse all xml versions. If the application uses nextText() extensively, use the following auxiliary method where nextText() is used.

private String safeNextText(XmlPullParser parser)  
         throws XmlPullParserException, IOException {  
     String result = parser.nextText();  
     if (parser.getEventType() != XmlPullParser.END_TAG) {  
         parser.nextTag();  
     }  
     return result;  
 }
Copy after login

Using a single XmlPullParse simplifies our maintenance and allows us to spend more energy on improving system performance.

The above is the content of the Be careful with the XmlPullParser.netText() method. For more related content, please pay attention to the PHP Chinese website (m.sbmmt.com)!


Related labels:
source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
About us Disclaimer Sitemap
php.cn:Public welfare online PHP training,Help PHP learners grow quickly!