Android에서 Pull 메서드를 사용하여 XML 파일을 해석하는 방법

13350 단어 xmlpull 해석
Pull 해석 방법은 응용 프로그램에 완전한 제어 문서를 어떻게 해석해야 하는지를 제공합니다.Android에서는 Pull 메서드에 지원되는 API를 주로 제공합니다

org.xmlpull.v1.XmlPullParser;
org.xmlpull.v1.XmlPullParserFactory;
두 가지 종류, 그 중에서 주로 사용하는 것은 XmlPullParser이고 XmlPullParserFactory는 하나의 공장으로 XmlPullParser 대상을 구축하는 데 사용된다.응용 프로그램은 XmlPullParser를 호출합니다.next () 등의 방법으로 이벤트를 생성한 다음 이벤트를 처리합니다.Push 방법과 달리 Push 방법은 Parser가 자발적으로 이벤트를 생성하여 응용 프로그램에 리셋하는 것을 볼 수 있다.Pull 방법은 Parser를 능동적으로 호출해야 이벤트가 발생합니다.만약에 XML의 문장이 이렇다면'James Elliott', author는 TAG,country는 ATTRIBUTE,'James Elliot'는 TEXT이다.문서를 해석하려면 XmlPullParser 객체를 작성해야 합니다

final XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
factory.setNamespaceAware(true);
final XmlPullParser parser = factory.newPullParser();
Pull 해석은 문서를 훑어보는 과정으로 매번 next (), next Tag (), next Token (), next Text () 를 호출할 때마다 문서를 앞으로 추진하고 Parser를 특정한 이벤트 위에 머무르게 하지만 후퇴할 수 없습니다.그리고 문서를 Parser에 설정합니다

parser.setInput(new StringReader("<author country=\"United States\">James Elliott</author>");
이때 문서가 초기화되었기 때문에 문서의 시작에 위치하고 이벤트는 START_DOCUMENT, XmlPullParser 사용 가능.getEventType()을 가져옵니다.그리고 next()를 호출하면 START_TAG, 이 이벤트는 프로그램에 탭이 시작되었음을 알려줍니다. getName () 을 호출하면 "author"로 되돌아옵니다.ext () 를 사용하면 TEXT 이벤트가 발생하고 getText () 를 호출하면 "James Elliott", ext () 를 호출하면 END_태그, 이것은 탭이 처리되었다는 것을 알려줍니다. 그리고 넥스트 (), END_문서 전체가 처리되었다는 것을 알려주는 문서입니다.next () 외에 next Token () 도 사용할 수 있습니다. 단지 COMMENT, CDSECT, DOCDECL, ENTITY 등 매우 상세한 정보를 되돌려줍니다.프로그램이 비교적 밑바닥 정보를 얻으면nextToken () 으로 상세한 이벤트를 구동하고 처리할 수 있습니다.주의해야 할 것은 TEXT 이벤트는 공백으로 돌아갈 수 있는 White Spaces, 예를 들어 줄 바꿈표나 공백 등이다.또 두 가지 매우 실용적인 방법이 있습니다. nextTag () 와 nextText () nextTag () - 우선 White Spaces를 무시합니다. 다음 방법이 START인지 확인할 수 있다면_TAG 또는 END_TAG, nextTag () 를 호출하여 바로 건너뛸 수 있습니다.일반적으로 START_태그 시 이 태그에 하위 태그가 포함되어 있는지 확인하면 nextTag () 를 호출하여 하위 태그를 생성하는 START_TAG 이벤트;END_TAG 시 문서의 끝이 아닌 것으로 확인되면 nextTag () 를 호출하여 다음 탭을 생성하는 START_TAG.이 두 가지 상황에서 넥스트 () 를 사용하면 TEXT 이벤트가 있지만 줄 바꾸기나 공백 문자가 되돌아옵니다.nextText() - START에서만 가능_TAG 시 호출됩니다.다음 요소가 TEXT이면 TEXT의 내용이 반환됩니다.다음 요소는 END_TAG 시, 즉 이 라벨의 내용이 비어 있으면 빈 문자열이 되돌아옵니다.이 메서드가 반환되면 Parser는 END_태그에예:

<author>James Elliott</author>
<author></author>
<author/>
START_TAG 시 nextText () 를 호출하여 "James Elliott""(empty)"(empty) 이 방법은 하위 탭이 없는 탭을 처리할 때 유용합니다.예:

<title>What Is Hibernate</title>
<author>James Elliott</author>
<category>Web</category>
다음 코드로 처리할 수 있습니다

        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;
            }
        }
이것은next()로 처리하는 것보다 훨씬 편리하고 가독성도 크게 강화되었다.마지막으로 XML을 해석하는 인스턴스 Android 프로그램을 첨부합니다

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();
    }
}

좋은 웹페이지 즐겨찾기