2

i'm using xmlpullparser in android to parse an xml document that looks like :

<top>
  <category>
    <name></name>
    <desc></desc>
    <songs>
      <song>
        <clip></clip>
        <thumb></thumb>
      </song>
      <song>
        <clip></clip>
        <thumb></thumb>
      </song>
    </songs>
  </category>
</top>

I tried this :

while (eventType != XmlPullParser.END_DOCUMENT && !done){
                String name = null;
                switch (eventType){
                    case XmlPullParser.START_DOCUMENT:
                        categoriesSong = new ArrayList<TopMousika>();
                        break;
                    case XmlPullParser.START_TAG:
                        name = parser.getName();
                        if (name.equalsIgnoreCase(CATEGORY)){
                            currentCategory = new TopMousika();
                            currentCategory.setId(parser.getAttributeValue(0));
                            currentCategory.setId(parser.getAttributeValue(1));
                        } else if (currentCategory != null){
                            if (name.equalsIgnoreCase(NAME)){
                                currentCategory.setName(parser.nextText());
                            } else if (name.equalsIgnoreCase(DESCRIPTION)){
                                currentCategory.setDescription(parser.nextText());
                            } else if (name.equalsIgnoreCase(THUMBNAIL)){
                                currentCategory.setThumbnail(parser.nextText());
                            } else if (name.equalsIgnoreCase(SONGS)){
                                songs = new ArrayList<SongMousika>();
                                if(name.equalsIgnoreCase(SONG)){
                                    currentSong = new SongMousika();
                                    currentSong.setId(parser.getAttributeValue(0));
                                    Log.d("TEST", "OK");
                                    songs.add(currentSong);
                                } else if (name.equalsIgnoreCase(TITLE)){
                                    Log.d("TEST", "OK2");
                                    currentSong.setTitle(parser.nextText());
                                } else if (name.equalsIgnoreCase(SINGER)){
                                    currentSong.setTitle(parser.nextText());
                                } else if (name.equalsIgnoreCase(THUMBNAIL)){
                                    currentSong.setTitle(parser.nextText());
                                } else if (name.equalsIgnoreCase(PUBLICATION_DATE)){
                                    currentSong.setTitle(parser.nextText());
                                } else if (name.equalsIgnoreCase(CLIP)){
                                    currentSong.setTitle(parser.nextText());
                                }
                                currentCategory.setSongs(songs);
                            }
                        }
                        break;
                    case XmlPullParser.END_TAG:
                        name = parser.getName();
                        if (name.equalsIgnoreCase(CATEGORY) && 
currentCategory != null){
                            currentCategory.setSongs(songs);
                            categoriesSong.add(currentCategory);
                        } else if (name.equalsIgnoreCase(TOP)){
                            done = true;
                        }
                        break;
                }
                eventType = parser.next();
            }

but I can not retrieve my Songs List.

can any one help me please ?

1 Answer 1

3

You seem to be expecting name to change magically between checks:

if (name.equalsIgnoreCase(SONGS)) {
    songs = new ArrayList<SongMousika>();
    if(name.equalsIgnoreCase(SONG)) {

How is it going to be SONG and SONGS? You need to keep pulling XML and react to each element name differently in the loop. So you'll probably have a bunch of if/else if statements without any nesting when reacting to a START_TAG event. (It's very likely to be worth pulling the handling of that into a separate method, by the way.)

EDIT: Okay, so you need to make each iteration of the loop just react to one tag. So your handling for a start tag would be something like:

case XmlPullParser.START_TAG:
    name = parser.getName();
    if (name.equalsIgnoreCase(CATEGORY)){
        currentCategory = new TopMousika();
        currentCategory.setId(parser.getAttributeValue(0));
        currentCategory.setId(parser.getAttributeValue(1));
    } else if (currentCategory != null) {
        if (name.equalsIgnoreCase(NAME)){
            currentCategory.setName(parser.nextText());
        } else if (name.equalsIgnoreCase(DESCRIPTION)){
            currentCategory.setDescription(parser.nextText());
        } else if (name.equalsIgnoreCase(THUMBNAIL)){
            currentCategory.setThumbnail(parser.nextText());
        } else if (name.equalsIgnoreCase(SONGS)){
            songs = new ArrayList<SongMousika>();
        } else if (songs != null) {
            if(name.equalsIgnoreCase(SONG)) {
                currentSong = new SongMousika();
                currentSong.setId(parser.getAttributeValue(0));
                Log.d("TEST", "OK");
                songs.add(currentSong);
            } else if (currentSong != null) {
                 else if (name.equalsIgnoreCase(TITLE)) {
                    Log.d("TEST", "OK2");
                    currentSong.setTitle(parser.nextText());
                } else if (name.equalsIgnoreCase(SINGER)){
                    currentSong.setSinger(parser.nextText());
                } else if (name.equalsIgnoreCase(THUMBNAIL))
                    // etc
                }
            }
        }

Note how in any path through there we never check for name having multiple values - we say:

  • Are we starting a new category?
    • If so, create it and remember it - then continue with the next iteration.
    • If not (and if we've got a category), are we starting a new song list?
    • If so, create it and remember it - then continue with the next iteration.
    • If not (and if we've got a song list), are we starting a new song?
      • If so, create it and remember it - then continue with the next iteration.
      • If not (and if we've got a song)...
      • Are we reading the title? If so, read the text and set it, then continue.
      • Are we reading the singer? If so, read the text and set it, then continue.
      • Are we reading the thumbnail? If so, read the text and set it, then continue.
      • etc
Sign up to request clarification or add additional context in comments.

3 Comments

thanks for your answer, i've followed the example in IBM DeveloperWorks link
@wael: No you haven't. Try to find an example in there where they check whether name equals one value and then within that condition check whether name equals another value. They check for currentMessage being null and check for various names within that, but that's not the same thing. Do you understand now why it's not working?
would you please explain more about You need to keep pulling XML and react to each element name differently in the loop

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.