Difficulty with XML nested tags with XMLPullParser in Android

喜欢而已 提交于 2019-12-10 11:11:15

问题


I'm trying to get the name and reading type="alpha".

I'm a beginner and English is not my first language, please pardon me. I've read about DOM, SAX, Simple, other StackOverflow posts, other samples but I don't understand and will like to learn about XMLPullParser in this case.

Sample XML below:

<feed>
    <title>Title</title>
    <item>

    <entry>
        <name>Name1</name>
        <record date="20001231">
            <reading type="alpha" value="100"/>
            <reading type="beta" value="200"/>
        </record>
    </entry>

    <entry>
        <name>Name2</name>
        <record date="20001231">
            <reading type="alpha" value="300"/>
            <reading type="beta" value="400"/>
        </record>
    </entry>

    </item>
</feed>

I've read this: http://developer.android.com/training/basics/network-ops/xml.html and the sample code works for the sample XML above without the <item> tags to get the name and record date.

private List<Entry> readFeed(XmlPullParser parser) throws XmlPullParserException, IOException {
    List<Entry> entries = new ArrayList<Entry>();

    parser.require(XmlPullParser.START_TAG, ns, "feed");
    while (parser.next() != XmlPullParser.END_TAG) {
        if (parser.getEventType() != XmlPullParser.START_TAG) {
            continue;
        }

        if (parser.getName().equals("entry")) {
            entries.add(readEntry(parser));
        } else {
            skip(parser);
        }
    }
    return entries;
}

What I've tried with the presence of <item> tags (but does not work) is:

private List<Entry> readFeed(XmlPullParser parser) throws XmlPullParserException, IOException {
    List<Entry> entries = new ArrayList<Entry>();

    parser.require(XmlPullParser.START_TAG, ns, "feed");
    while (parser.next() != XmlPullParser.END_TAG) {
        if (parser.getEventType() != XmlPullParser.START_TAG) {
            continue;
        }

        if (parser.getName().equals("item")) {

            parser.next();

            while (parser.next() != XmlPullParser.END_TAG) {
                if (parser.getEventType() != XmlPullParser.START_TAG) {
                    continue;
                }

                if (parser.getName().equals("entry")) {
                    entries.add(readEntry(parser));
                } else {
                    skip(parser);
                }
            }

        } else {
            skip(parser);
        }
    }
    return entries;
}

If I can solve that, I will be able to read the name and record date, but what I'm trying to get is the name and reading type="alpha", which I don't know how to get the nested reading type="alpha".

Many thanks in advance.


回答1:


you keep looping and when

parser.getEventType() == XmlPullParser.START_TAG && parser.getName().equals("name")

you can retrive the value of the tag name with getText():

you will call then

parser.next();
String name = parser.getText();

when

parser.getEventType() == XmlPullParser.START_TAG && parser.getName().equals("reading")

you want to read your attributes, Eg. <reading type="alpha" value="300"/>

String type = parser.getAttributeValue(null, "type");
String value = parser.getAttributeValue(null, "value");

Edit:

private void readFeed(XmlPullParser parser) throws IOException, XmlPullParserException {
    int eventType = parser.getEventType();
    while (eventType != XmlPullParser.END_DOCUMENT) {
        if (eventType == XmlPullParser.START_TAG) {
            String name = parser.getName();
            if (name == null) {
                continue;
            }
            if (name.equals("reading")) {
                Log.e(getClass().getSimpleName()," " + parser.getAttributeValue(null, "type"));
                Log.e(getClass().getSimpleName(), " " + parser.getAttributeValue(null, "value"));
            }
        }
        eventType = parser.next();
    }
}



回答2:


You can try this function

 private List readFeed(XmlPullParser parser) throws XmlPullParserException, IOException {
    List entries = new ArrayList();

    parser.require(XmlPullParser.START_TAG, ns, "feed");
    while (parser.next() != XmlPullParser.END_TAG) {
        if (parser.getEventType() != XmlPullParser.START_TAG) {
            continue;
        }
        String name = parser.getName();
        // Starts by looking for the item tag
        if (name.equals("item")) {
            parser.require(XmlPullParser.START_TAG, ns, "item");
            while (parser.next() != XmlPullParser.END_TAG) {
                if (parser.getEventType() != XmlPullParser.START_TAG) {
                    continue;
                }
                // and then get the entry here
                if (name.equals("entry")) {
                    entries.add(readEntry(parser));
                }
            }
        } else {
            skip(parser);
        }
    }  
    return entries;
}

Where readEntry Function is :

private Entry readEntry(XmlPullParser parser) throws XmlPullParserException, IOException {
    parser.require(XmlPullParser.START_TAG, ns, "entry");
    String name = null;
    Record record = null;
    while (parser.next() != XmlPullParser.END_TAG) {
        if (parser.getEventType() != XmlPullParser.START_TAG) {
            continue;
        }
        String name = parser.getName();
        if (name.equals("name")) {
            parser.require(XmlPullParser.START_TAG, ns, "name");
            String title = readText(parser);
            parser.require(XmlPullParser.END_TAG, ns, "name");
        } else if (name.equals("record")) {
            // Try to figure it out by yourself for practice ;)
        } else {
            skip(parser);
        }
    }
    return new Entry(title, summary, link);
}



回答3:


I also got same error and my solution was simple just check right

String name=parser.getName();

parser.require(XmlPullParser.START_TAG, nameSpace, first_tag_key);

if name and first_tag_right is not same then you will get this exception.

THIS IS A GENERIC ANSWER FOR ANY USER IF IN CASE HE GET THIS ERROR.




回答4:


The accepted answer works only because you only have nested tags but what if you had unnested tags and you only wanted the nested ones ?

One way you can do this is :

    while (eventType != XmlPullParser.END_DOCUMENT ) {

        // check for the parent tag
        if (eventType == XmlPullParser.START_TAG && "item".equals(xpp.getName())) {
            eventType = xpp.next();

            // loop the parent tag elements until we reach the end of the parent tag
            while (eventType != XmlPullParser.END_TAG && !"item".equals(xpp.getName())) {

                // check the children tags
                if ("title".equals(xpp.getName()))
                    // do something
                else if ("link".equals(xpp.getName()))
                    // do something
                xpp.next();
            }
        }
        eventType = xpp.next();
    }

The basic idea is one while loop for each parent tag and corresponding ifs for each children.



来源:https://stackoverflow.com/questions/33341391/difficulty-with-xml-nested-tags-with-xmlpullparser-in-android

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!