[Android] Syntax Parsing error correction !!

Source: Internet
Author: User

Before talking about this error, read the following code.[◆ The following parsing method is incorrect ×]

Import Java. util. arraylist; import Java. util. list; import Org. XML. sax. attributes; import Org. XML. sax. saxexception; import Org. XML. sax. helpers. defaulthandler; import android. util. log; public class xmlhandler extends defaulthandler {private final string tag = This. getclass (). getsimplename ();/** tag definition */private final string tag_article = "article"; private final string tag_articleid = "ArticleID"; private F Inal string tag_title = "title"; private final string tag_date = "date"; private final string tag_smallpictures = "smallpictures"; private final string tag_largepictures = "largepictures "; private final string tag_category = "category"; Private Static final string tag_headnote = "headnote"; Private Static final string tag_subtitle = "subtitle"; Private Static final string tag_source = "Source "; // t being parsed Agprivate string currentname; // Private news = NULL for a single article; // Private list of article lists <News> newslist = NULL; // resolution start time private long start_time; private Boolean flag = false; @ overridepublic void characters (char [] CH, int start, int length) throws saxexception {super. characters (CH, start, length); If (! Flag) {return;} // value: string value = new string (CH, start, length); log. D (TAG, "element:" + currentname + "element value:" + value); If (value! = NULL) {If (tag_articleid.equals (currentname) {NEWS. setarticleid (value);} else if (tag_title.equals (currentname) {NEWS. settitle (value);} else if (tag_date.equals (currentname) {NEWS. setdate (value);} else if (tag_category.equals (currentname) {NEWS. setcategory (value);} else if (tag_smallpictures.equals (currentname) {NEWS. setsmallpicture (value);} else if (tag_largepictures.equals (currentname) {NEWS. se Tlargepicture (value);} else if (tag_headnote.equals (currentname) {NEWS. setheadnote (value);} else if (tag_subtitle.equals (currentname) {NEWS. setsubtitle (value);} else if (tag_source.equals (currentname) {NEWS. setsource (value) ;}}@ overridepublic void startdocument () throws saxexception {super. startdocument (); start_time = system. currenttimemillis (); newslist = new arraylist <News> () ;}@ overridepublic voi D startelement (string Uri, string localname, string QNAME, attributes) throws saxexception {super. startelement (Uri, localname, QNAME, attributes); this. currentname = localname; flag = true; If (tag_article.equals (localname) {NEWS = new news () ;}@ overridepublic void endelement (string Uri, string localname, string QNAME) throws saxexception {super. endelement (Uri, localname, QNAME); flag = Fals E; If (tag_article.equals (localname) {newslist. add (News) ;}@ overridepublic void enddocument () throws saxexception {super. enddocument (); long end = system. currenttimemillis (); log. D (TAG, "parse list's XML cost:" + (end-start_time) + "!! ");}}

Baidu or Google "Android sax parsing", and the sample provided is the same without exception. This is even true for some books, such as Android development entry and practice. (This book has been confirmed by myself. Other books are unknown)


That's right. In general, this write is acceptable, and it is correct in most cases. But sometimes errors occur. At this time, you are usually confused. What is going on? The data is correct. It seems that it is okay to parse some code. It's really strange. The problem lies in the above Code !!

We all think that the process of parsing a sax statement is roughly as follows:

Startdocument-> startelement-> characters-> endelement-> enddocument

That's right. startelement reads the starting tag and endelement reads the ending tag. What about characters?Of course, it is true to read the value, but everyone really thinks that characters only runs once and reads all the content at once. This is the error!

In fact, characters may be executed multiple times. When the content contains carriage return, \ t, and so on, it is likely to be executed multiple times. Some may say, if I don't have these, will I only execute them once? Let's take a look at my actual test results:

 


XML for testing is as follows:

<News> <Article> <ArticleID> 1000555 </ArticleID> <title> <! [CDATA [Zhengzhou "first bridge in Asia" was opened to a dangerous bridge for six years]> </title> <date> 14:23:52 </date> <smallpictures> livenews/images/ssf-png </smallpictures> <largepictures> livenews/images/lw.png </largepictures> <Category> </Category> 

Obviously, characters performs the <ArticleID> 1000553 </ArticleID> parsing twice and reads the content "1000553" twice .. the final result in the above method is ArticleID = 00553. If your application needs to further obtain the content based on this ID, isn't it difficult? (For example, you can obtain detailed news content by ID)

Okay, I don't have to talk about it anymore. Let's take a look at the correct method!【★The following parsing method is correct √]

Import Java. util. arraylist; import Java. util. list; import Org. XML. sax. attributes; import Org. XML. sax. saxexception; import Org. XML. sax. helpers. defaulthandler; import android. util. log; public class xmlhandler extends defaulthandler {private final string tag = This. getclass (). getsimplename ();/** tag definition */private final string tag_article = "article"; private final string tag_articleid = "ArticleID"; private F Inal string tag_title = "title"; private final string tag_date = "date"; private final string tag_smallpictures = "smallpictures"; private final string tag_largepictures = "largepictures "; private final string tag_category = "category"; Private Static final string tag_headnote = "headnote"; Private Static final string tag_subtitle = "subtitle"; Private Static final string tag_source = "Source "; // single article priv Ate News news = NULL; // article list private list <News> newslist = NULL; // resolution start time private long start_time; // (1) private stringbuilder sb = new stringbuilder (); @ overridepublic void characters (char [] CH, int start, int length) throws saxexception {super. characters (CH, start, length); // (2) no matter how many characters are executed during startelement to endelement, the content will be added to stringbuilder, NO content Sb will be lost. append (CH, start, length) ;}@ overridepublic voi D startdocument () throws saxexception {super. startdocument (); start_time = system. currenttimemillis (); newslist = new arraylist <News> () ;}@ overridepublic void startelement (string Uri, string localname, string QNAME, attributes) throws saxexception {super. startelement (Uri, localname, QNAME, attributes); // (3) Clear the historical data Sb when you start to collect new tag data. setlength (0); If (tag_article.equals (localname) {NEWS = new n EWS () ;}@ overridepublic void endelement (string Uri, string localname, string QNAME) throws saxexception {super. endelement (Uri, localname, QNAME); // (4) the original value in characters is changed to string value = sb. tostring (); If (tag_articleid.equals (localname) {NEWS. setarticleid (value);} else if (tag_title.equals (localname) {NEWS. settitle (value);} else if (tag_date.equals (localname) {NEWS. setdate (value);} else if (tag_cat Egory. equals (localname) {NEWS. setcategory (value);} else if (tag_smallpictures.equals (localname) {NEWS. setsmallpicture (value);} else if (tag_largepictures.equals (localname) {NEWS. setlargepicture (value);} else if (tag_headnote.equals (localname) {NEWS. setheadnote (value);} else if (tag_subtitle.equals (localname) {NEWS. setsubtitle (value);} else if (tag_source.equals (localname) {NEWS. setsource (value );} If (tag_article.equals (localname) {newslist. add (News) ;}@ overridepublic void enddocument () throws saxexception {super. enddocument (); long end = system. currenttimemillis (); log. D (TAG, "parse list's XML cost:" + (end-start_time) + "!! ");}}

There are three points:

1. In startelement, new stringbuilder (); or SB. setlength (0); (I suggest the latter)
2. In characters, SB. append (CH, start, length );
3. When endelement is enabled, SB. tostring (); in this case, the content in stringbuilder is the resolution result.


In this way, data will not be lost in a strange way. (At the same time, you do not need to set another currenttag like the wrong method. The logic is complicated and there are still errors )!


I hope you can see this article as soon as possible. Don't get it again !!!


Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.