Practical Android skills: Use the pull method to parse XML files

Source: Internet
Author: User

The pull parsing method gives the application full control on how the document should be parsed. Android provides APIs that support the pull method, mainly

org.xmlpull.v1.XmlPullParser;org.xmlpull.v1.XmlPullParserFactory;

Xmlpullparser and xmlpullparserfactory are used to build xmlpullparser objects.
The application generates an event by calling xmlpullparser. Next () and other methods, and then processes the event. We can see that it is different from the push method. The Push method is generated by parser and called back to the application. The pull method actively calls the parser method to generate events.
Assume that the statement in XML is like this: "<author Country =" United States "> James Elliott </author>", author is tag, country is attribute, "James Elliott" is text.
To parse the document, you must first construct an xmlpullparser object.

        final XmlPullParserFactory factory = XmlPullParserFactory.newInstance();        factory.setNamespaceAware(true);        final XmlPullParser parser = factory.newPullParser();

Pull Parsing is a process of traversing documents. Every time you call next (), nexttag (), nexttoken (), and nexttext (), the document is pushed forward and parser stays on some events, but it cannot be regressed.
Set the document to parser.

        parser.setInput(new StringReader("<author country=\"United States\">James Elliott</author>");

At this time, the document has just been initialized, so it should be at the beginning of the document, the event should be start_document, which can be obtained through xmlpullparser. geteventtype. Then call next () to generate

  • Start_tag. This event tells the application that a tag has already started. If getname () is called, "author" is returned, and next () will generate
  • Text event. If gettext () is called, "James Elliott" will be returned, and next () will generate
  • End_tag. This indicates that a tag has been processed. Next () will generate
  • End_document, which tells you that the entire document has been processed.

In addition to next (), nexttoken () can also be used, but it will return more detailed events, such as comment, cdsect, docdecl, entity and so on. If the program gets the underlying information, you can use nexttoken () to drive and process detailed events. Note that text events may return blank white spaces, such as line breaks or spaces.
In addition, there are two very practical methods: nexttag () and nexttext ()
Nexttag () -- first, it ignores white spaces. If you can determine the next one is start_tag or end_tag, you can call nexttag () to jump over directly. Generally, it has two functions: When start_tag, if you can determine that this tag contains a sub-tag, you can call nexttag () to generate the start_tag event of the sub-tag; When end_tag, if it is not the end of the document, you can call nexttag () to generate the start_tag of the next tag. In both cases, if next () is used, a text event is generated, but a line break or blank space character is returned.
Nexttext () -- it can only be called at start_tag. When the next element is text, the content of text will be returned. When the next element is end_tag, that is, the content of this label is null, then the Null String is returned. After this method is returned, parser stops at end_tag. For example:

<author>James Elliott</author><author></author><author/>

When start_tag is used, call nexttext () and return the following values in sequence:
"James Elliott"
"" (Empty)
"" (Empty)
This method is useful when processing tags without sub-tags. For example:

<title>What Is Hibernate</title><author>James Elliott</author><category>Web</category>

You can use the following code:

        while (eventType != XmlPullParser.END_TAG) {            switch (eventType) {            case XmlPullParser.START_TAG:                tag = parser.getName();                final String content = parser.nextText();                Log.e(TAG, tag + ": [" + content + "]");                eventType = parser.nextTag();                break;            default:                break;            }        }

This is much easier to process than using next (), and the readability is also greatly enhanced.
Finally, an android program for parsing XML is attached.

import java.io.IOException;import java.io.InputStream;import org.xmlpull.v1.XmlPullParser;import org.xmlpull.v1.XmlPullParserException;import org.xmlpull.v1.XmlPullParserFactory;import android.util.Log;public class RssPullParser extends RssParser {    private final String TAG = FeedSettings.GLOBAL_TAG;        private InputStream mInputStream;        public RssPullParser(InputStream is) {        mInputStream = is;    }        public void parse() throws ReaderBaseException, XmlPullParserException, IOException {        if (mInputStream == null) {            throw new ReaderBaseException("no input source, did you initialize this class correctly?");        }        final XmlPullParserFactory factory = XmlPullParserFactory.newInstance();        factory.setNamespaceAware(true);        final XmlPullParser parser = factory.newPullParser();                parser.setInput(mInputStream);        int eventType = parser.getEventType();        if (eventType != XmlPullParser.START_DOCUMENT) {            throw new ReaderBaseException("Not starting with 'start_document'");        }        eventType = parseRss(parser);        if (eventType != XmlPullParser.END_DOCUMENT) {            throw new ReaderBaseException("not ending with 'end_document', do you finish parsing?");        }        if (mInputStream != null) {            mInputStream.close();        } else {            Log.e(TAG, "inputstream is null, XmlPullParser closed it??");        }    }        /**     * Parsing the Xml document. Current type must be Start_Document.     * After calling this, Parser is positioned at END_DOCUMENT.     * @param parser     * @return event end_document     * @throws XmlPullParserException     * @throws ReaderBaseException     * @throws IOException     */    private int parseRss(XmlPullParser parser) throws XmlPullParserException, ReaderBaseException, IOException {        int eventType = parser.getEventType();        if (eventType != XmlPullParser.START_DOCUMENT) {            throw new ReaderBaseException("not starting with 'start_document', is this a new document?");        }        Log.e(TAG, "starting document, are you aware of that!");        eventType = parser.next();        while (eventType != XmlPullParser.END_DOCUMENT) {            switch (eventType) {            case XmlPullParser.START_TAG: {                Log.e(TAG, "start tag: '" + parser.getName() + "'");                final String tagName = parser.getName();                if (tagName.equals(RssFeed.TAG_RSS)) {                    Log.e(TAG, "starting an RSS feed <<");                    final int attrSize = parser.getAttributeCount();                    for (int i = 0; i < attrSize; i++) {                        Log.e(TAG, "attr '" + parser.getAttributeName(i) + "=" + parser.getAttributeValue(i) + "'");                    }                } else if (tagName.equals(RssFeed.TAG_CHANNEL)) {                    Log.e(TAG, "\tstarting an Channel <<");                    parseChannel(parser);                }                break;            }            case XmlPullParser.END_TAG: {                Log.e(TAG, "end tag: '" + parser.getName() + "'");                final String tagName = parser.getName();                if (tagName.equals(RssFeed.TAG_RSS)) {                    Log.e(TAG, ">> edning an RSS feed");                } else if (tagName.equals(RssFeed.TAG_CHANNEL)) {                    Log.e(TAG, "\t>> ending an Channel");                     }                break;            }            default:                break;            }            eventType = parser.next();        }        Log.e(TAG, "end of document, it is over");        return parser.getEventType();    }        /**     * Parse a channel. MUST be start tag of an channel, otherwise exception thrown.     * Param XmlPullParser     * After calling this function, parser is positioned at END_TAG of Channel.     * return end tag of a channel     * @throws XmlPullParserException     * @throws ReaderBaseException     * @throws IOException     */    private int parseChannel(XmlPullParser parser) throws XmlPullParserException, ReaderBaseException, IOException {        int eventType = parser.getEventType();        String tagName = parser.getName();        if (eventType != XmlPullParser.START_TAG || !RssFeed.TAG_CHANNEL.equals(tagName)) {            throw new ReaderBaseException("not start with 'start tag', is this a start of a channel?");        }        Log.e(TAG, "\tstarting " + tagName);        eventType = parser.nextTag();        while (eventType != XmlPullParser.END_TAG) {            switch (eventType) {            case XmlPullParser.START_TAG: {                final String tag = parser.getName();                if (tag.equals(RssFeed.TAG_IMAGE)) {                    parseImage(parser);                } else if (tag.equals(RssFeed.TAG_ITEM)) {                    parseItem(parser);                } else {                    final String content = parser.nextText();                    Log.e(TAG, tag + ": [" + content + "]");                }                // now it SHOULD be at END_TAG, ensure it                if (parser.getEventType() != XmlPullParser.END_TAG) {                    throw new ReaderBaseException("not ending with 'end tag', did you finish parsing sub item?");                }                eventType = parser.nextTag();                break;            }            default:                break;            }        }        Log.e(TAG, "\tending " + parser.getName());        return parser.getEventType();    }        /**     * Parse image in a channel.     * Precondition: position must be at START_TAG and tag MUST be 'image'     * Postcondition: position is END_TAG of '/image'     * @throws IOException     * @throws XmlPullParserException     * @throws ReaderBaseException     */    private int parseImage(XmlPullParser parser) throws XmlPullParserException, IOException, ReaderBaseException {        int eventType = parser.getEventType();        String tag = parser.getName();        if (eventType != XmlPullParser.START_TAG || !RssFeed.TAG_IMAGE.equals(tag)) {            throw new ReaderBaseException("not start with 'start tag', is this a start of an image?");        }        Log.e(TAG, "\t\tstarting image " + tag);        eventType = parser.nextTag();        while (eventType != XmlPullParser.END_TAG) {            switch (eventType) {            case XmlPullParser.START_TAG:                tag = parser.getName();                Log.e(TAG, tag + ": [" + parser.nextText() + "]");                // now it SHOULD be at END_TAG, ensure it                if (parser.getEventType() != XmlPullParser.END_TAG) {                    throw new ReaderBaseException("not ending with 'end tag', did you finish parsing sub item?");                }                eventType = parser.nextTag();                break;            default:                break;            }        }        Log.e(TAG, "\t\tending image " + parser.getName());        return parser.getEventType();    }        /**     * Parse an item in a channel.     * Precondition: position must be at START_TAG and tag MUST be 'item'     * Postcondition: position is END_TAG of '/item'     * @throws IOException     * @throws XmlPullParserException     * @throws ReaderBaseException     */    private int parseItem(XmlPullParser parser) throws XmlPullParserException, IOException, ReaderBaseException {        int eventType = parser.getEventType();        String tag = parser.getName();        if (eventType != XmlPullParser.START_TAG || !RssFeed.TAG_ITEM.equals(tag)) {            throw new ReaderBaseException("not start with 'start tag', is this a start of an item?");        }        Log.e(TAG, "\t\tstarting " + tag);        eventType = parser.nextTag();        while (eventType != XmlPullParser.END_TAG) {            switch (eventType) {            case XmlPullParser.START_TAG:                tag = parser.getName();                final String content = parser.nextText();                Log.e(TAG, tag + ": [" + content + "]");                // now it SHOULD be at END_TAG, ensure it                if (parser.getEventType() != XmlPullParser.END_TAG) {                    throw new ReaderBaseException("not ending with 'end tag', did you finish parsing sub item?");                }                eventType = parser.nextTag();                break;            default:                break;            }        }        Log.e(TAG, "\t\tending " + parser.getName());        return parser.getEventType();    }}
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.