Android parses XML files (II)

Source: Internet
Author: User
Tags call back tagname

In the previous section, we used DOM to parse XML documents. This method conforms to our daily thinking and is easy to use. However, it directly transfers documents to the memory, which is relatively memory-consuming. Here we can use another method to parse XML, which is the sax method.

Sax is: Simple API for XML

Sax is event-driven. Of course, Android's event mechanism is based on callback functions. when parsing XML documents with sax, an event will be called back when the start and end tags of the read documents are obtained, when reading other nodes and content, an event is also called back.

Since events are involved, there is an event source and an event processor. In the sax interface, the event source is xmlreader In the org. xml. Sax package. It parses the XML document through the Parser () method and generates events. The event processor is the contenthander, dtdhander, errorhandler, and entityresolver interfaces in the org. xml. Sax package.

Xmlreader connects to contenthander, dtdhander, errorhandler, and entityresolver through the corresponding event processor registration method setxxxx (). For details, see the following table:

However, we do not need to inherit these four interfaces. the SDK provides the defaulthandler class for processing. Some Major Event Callback methods of the defaulthandler class are as follows:

From the above, we need xmlreader and defaulthandler to parse XML.

The solution is as follows:

1: Create a saxparserfactory object

2: According to the saxparserfactory. newsaxparser () method, a saxparser parser is returned.
3: Get the event source object xmlreader according to the saxparser parser
4: instantiate a defaulthandler object

5: connect the event source object xmlreader to the event processing class defaulthandler.

6: Call the parse method of xmlreader to obtain XML data from the input source.

7: return the data set we need through defaulthandler.

CodeAs follows:

View code

 Public  List  <  River  >  Parse (string xmlpath ){
List < River > Rivers = Null ;
Saxparserfactory Factory = Saxparserfactory. newinstance ();
Try {
Saxparser parser = Factory. newsaxparser ();
// Get event Source
Xmlreader = Parser. getxmlreader ();
// Set Processor
Riverhandler Handler = New Riverhandler ();
Xmlreader. setcontenthandler (handler );
// Parse XML documents
// Xmlreader. parse (New inputsource (new URL (xmlpath). openstream ()));
Xmlreader. parse ( New Inputsource ( This . Context. getassets (). Open (xmlpath )));
Rivers = Handler. getrivers ();
} Catch (Parserconfigurationexception e ){
// Todo auto-generated Catch Block
E. printstacktrace ();
} Catch (Saxexception e ){
// Todo auto-generated Catch Block
E. printstacktrace ();
} Catch (Ioexception e ){
E. printstacktrace ();
}

Return Rivers;
}

The focus is on processing each element node, attribute, text content, and document content in the defaulthandler object.

As mentioned above, defaulthandler is based on the event processing model. The basic processing method is to call back the startdocument method when the SAX Parser navigating to the start tag of the document, and to call back the enddocument method when the end tag of the document. The SAX Parser calls back the startelement method when the element starts the tag, calls back the characters method when it is navigating to its text content, and calls back the endelement method when the Tag ends.

Based on the above explanation, we can draw the following logic for processing XML documents:

1: When navigation to the document start label, in the callback function startdocument, You can do not deal with, of course you can verify the UTF-8 and so on.

2: When you navigate to rivers to start the tag, you can instantiate a set in the callback method startelement to store the list, but we don't need it here because it has been instantiated in the constructor.

3: When you navigate to the river start label, it indicates that the river object needs to be instantiated. Of course, the river label also contains the name and length attributes. Therefore, the attribute value, attributes, must be taken out after the river is instantiated. getvalue (name) is used to assign a Boolean to the river object and add a Boolean to the river label to indicate that the river element is located.

4: Of course, there are also sub-tags (nodes) in the river tag, but the SAX Parser does not know what label to navigate to. It only knows the start and the end. So how can we make it recognize our labels? Of course, you need to determine, so you can use the string localname parameter in the callback method startelement to compare our tag string with this parameter. We must also let sax know. Now we are navigating to a tag, so add a true attribute to let the SAX Parser know. Therefore

5: it will also navigate to the text label (that is, the content in </img>), the callback method characters, in this method, we usually extract the content in </img> and save it.

6: Of course, it will definitely navigate to the end tag </river> or </rivers>. If it is a </river> tag, remember to add the river object to the list. If it is a sub-tag in the river </introduction>, set the Boolean tag marked previously to false.

The following code can be implemented based on the above Implementation ideas:

View code

 /** Navigate to start tag trigger *  */  
Public Void Startelement (string Uri, string localname, string QNAME, attributes ){
String tagname = Localname. Length () ! = 0 ? Localname: QNAME;
Tagname = Tagname. tolowercase (). Trim ();
// If the river tag is read, the river
If (Tagname. Equals (river )){
Isriver = True ;
River = New River ();
/** After navigation to the river Start Node * */
River. setname (attributes. getvalue (name ));
River. setlength (integer. parseint (attributes. getvalue (length )));
}
// Then read other nodes
If (Isriver ){
If (Tagname. Equals (Introduction )){
Xintroduction = True ;
} Else If (Tagname. Equals (imageurl )){
Ximageurl = True ;
}
}
}

/** Navigate to the end tag to trigger * */
Public Void Endelement (string Uri, string localname, string QNAME ){
String tagname = Localname. Length () ! = 0 ? Localname: QNAME;
Tagname = Tagname. tolowercase (). Trim ();

// If the river label is read, add the river to the collection.
If (Tagname. Equals (river )){
Isriver = True ;
Rivers. Add (river );
}
// Then read other nodes
If (Isriver ){
If (Tagname. Equals (Introduction )){
Xintroduction = False ;
} Else If (Tagname. Equals (imageurl )){
Ximageurl = False ;
}
}
}

// Here is the callback when reading the node content
Public Void Characters ( Char [] CH, Int Start, Int Length ){
// Set attribute values
If (Xintroduction ){
// Solve the null Problem
River. setintroduction (river. getintroduction () = Null ? "" : River. getintroduction () + New String (CH, start, length ));
} Else If (Ximageurl ){
// Solve the null Problem
River. setimageurl (river. getimageurl () = Null ? "" : River. getimageurl () + New String (CH, start, length ));
}
}

The running result is as follows:

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.