4

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.

0

4 Answers 4

1

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);
}
Sign up to request clarification or add additional context in comments.

3 Comments

parser.require(XmlPullParser.START_TAG, ns, "title"); String title = readText(parser); parser.require(XmlPullParser.END_TAG, ns, "title"); Why is title used in this case?
@TryingToLearn Sorry wrong key, see my edited answer.
The readFeed does not get to <entry> just like the code I posted :( I don't know how the nested tag can be accessed
0

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

4 Comments

Thanks, it helped me to understand how to retrieve the values. But how should the loop work to reach the nested tags to be able to reach the condition? First nested part will be those inside <item>, second would be inside <record> (<reading>). Is there a way to loop through the entire XML document to only reach the tags I want?
Any idea on how to reach the nested tags? I've tried the one in the other post and a few other places and still unable to do so... :/
If I were in you I would start removing continue; and log the tag's name at every iteration. I could write the parser for your, but it would be nice if you could figure this out.
After removing continue; it crashes. Could you elaborate more on how this can be done? Or provide a sample as to how the nested tags can be handled, so I can understand it better and figure it out. The logcat also displays "com.example.android.networkusage E/eglCodecCommon: glUtilsParamSize: unknow param 0x00000b44 com.example.android.networkusage E/eglCodecCommon: glUtilsParamSize: unknow param 0x00000bd0 com.example.android.networkusage E/eglCodecCommon: **** ERROR unknown type 0x73000d (glSizeof,72)" multiple times, any idea what that means?
0

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.

Comments

0

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.