1

I'm currently creating a parser for an XML-file and everything works fine until I add an extra option to retrieve a link. I have several tags of the same name and I want one specific tag with a specific attribute value.

...
<artist>
    <name>Venom</name>
    <mbid>5ddddef1-fd5a-4ca8-8e89-df4adff4239b</mbid>
    <url>Venom</url>
    <image size="small">http://userserve-ak.last.fm/serve/34/35628151.png</image>
    <image size="medium">http://userserve-ak.last.fm/serve/64/35628151.png</image>
    <image size="large">http://userserve-ak.last.fm/serve/126/35628151.png</image>
    <image size="extralarge">http://userserve-ak.last.fm/serve/252/35628151.png</image>
</artist>
...

I'm fishing for the link in "extralarge".

My current code:

...
private TrackInfo readTrack(XmlPullParser parser) throws XmlPullParserException, IOException {
    parser.require(XmlPullParser.START_TAG, ns, "track");
    String artist = null;
    String artistPic = null;
    String artisMbid = null;
    String song = null;
    String album = null;
    while (parser.next() != XmlPullParser.END_TAG) {
        if (parser.getEventType() != XmlPullParser.START_TAG) {
            continue;
        }
        String name = parser.getName();
        if (name.equals("artist")) {

            parser.require(XmlPullParser.START_TAG, ns, "artist");
            while (parser.next() != XmlPullParser.END_TAG) {
                if (parser.getEventType() != XmlPullParser.START_TAG) {
                    continue;
                }
                String artistName = parser.getName();
                if (artistName.equals("name")) {
                    artist = readArtist(parser);
                } else if (artistName.equals("mbid")) {
                    artisMbid = readArtistMbid(parser);
                } else if (artistName.equals("image")) {
                    artistPic = readArtistPic(parser);
                } else {
                    skip(parser);
                }
            }
        } else if (name.equals("name")) {
            song = readSong(parser);
        } else if (name.equals("album")) {
            album = readAlbum(parser);
        } else {
            skip(parser);
        }
    }
    return new TrackInfo(artist, artistPic, artisMbid, song, album);
}

...

private String readArtistPic(XmlPullParser parser) throws XmlPullParserException, IOException {
    String artistPic = "";
    parser.require(XmlPullParser.START_TAG, ns, "image");
    String tag = parser.getName();
    String relType = parser.getAttributeValue(null, "size");
    if (tag.equals("image")) {
        if (relType.equals("extralarge")) {
            artistPic = readText(parser);
            parser.nextTag();
        }
    }
    parser.require(XmlPullParser.END_TAG, ns, "image");

    return artistPic;
}

...

private String readText(XmlPullParser parser) throws XmlPullParserException, IOException {
    String result = "";
    if (parser.next() == XmlPullParser.TEXT) {
        result = parser.getText();
        parser.nextTag();
    }
    return result;
}
...

The error:

E/CurrentTrackFragment logging﹕ XmlPullParserException: org.xmlpull.v1.XmlPullParserException: expected: END_TAG {null}image (position:START_TAG <image size='small'>@10:29 in java.io.InputStreamReader@52a3a014)

Anybody any idea how to handle this?

Solution!

I started working with the example Raghunandan gave me. In the end I only simplified my code and added the 'check = true' he suggested.

private TrackInfo readTrack(XmlPullParser parser) throws XmlPullParserException, IOException {
    parser.require(XmlPullParser.START_TAG, ns, "track");
    boolean nowPlaying = false;
    String artist = null;
    String artistPic = null;
    String artistMbid = null;
    String song = null;
    String songUrl = null;
    String album = null;
    String albumPic = null;
    int playedUts = 0;
    while (parser.next() != XmlPullParser.END_TAG) {
        if (parser.getEventType() != XmlPullParser.START_TAG) {
            continue;
        }
        String name = parser.getName();
        if (name.equals("artist")) {
            parser.require(XmlPullParser.START_TAG, ns, "artist");
            while (parser.next() != XmlPullParser.END_TAG) {
                if (parser.getEventType() != XmlPullParser.START_TAG) {
                    continue;
                }
                String artistName = parser.getName();
                if (artistName.equals("name")) {
                    artist = readArtist(parser);
                } else if (artistName.equals("mbid")) {
                    artistMbid = readArtistMbid(parser);
                } else if (artistName.equals("image")) {
                    boolean check = false;
                    String imagesize = parser.getAttributeValue(null, "size");
                    if (imagesize.equals("extralarge")) {
                        check = true;
                    }
                    if (check) {
                        artistPic = readArtistPic(parser);
                    } else {
                        parser.nextText();
                    }
                } else {
                    skip(parser);
                }
            }
        } else if (name.equals("name")) {
            song = readSong(parser);
        } else if (name.equals("url")) {
            songUrl = readSongUrl(parser);
        } else if (name.equals("album")) {
            album = readAlbum(parser);
        } else if (name.equals("date")) {
            playedUts = Integer.parseInt(readUts(parser));
        } else {
            skip(parser);
        }
    }
    return new TrackInfo(nowPlaying, artist, artistPic, artistMbid, song, songUrl,
            album, albumPic, playedUts);
}

...

private String readArtistPic(XmlPullParser parser) throws XmlPullParserException, IOException {
    parser.require(XmlPullParser.START_TAG, ns, "image");
    String artistPic = readText(parser);
    parser.require(XmlPullParser.END_TAG, ns, "image");
    return artistPic;
}

...
3
  • Do you debug your app, i think parser.require(XmlPullParser.START_TAG, ns, "image"); this line you are getting error is it Commented Apr 24, 2014 at 8:00
  • without full stacktrace hard to tell what's wrong. i can post an example Commented Apr 24, 2014 at 8:41
  • I'm desperately trying to get a stacktrace, but the above is the only info I get back. Commented Apr 24, 2014 at 18:28

1 Answer 1

3

Without the full stacktrace its hard to point the mistake. However the below works.

 public class XMLPullParserHandler {

    private String text;

    public XMLPullParserHandler() {

    }
    public Void parse(InputStream is) { // pas the input stream
        XmlPullParserFactory factory = null;
        XmlPullParser parser = null;
        try {
            factory = XmlPullParserFactory.newInstance();
            factory.setNamespaceAware(true);
            parser = factory.newPullParser();

            parser.setInput(is, null);
            boolean check =false;

           //factory instantiates an object

            int eventType = parser.getEventType();
            while (eventType != XmlPullParser.END_DOCUMENT) {
                String tagname = parser.getName();
                switch (eventType) {
                case XmlPullParser.START_TAG:
                    if (tagname.equalsIgnoreCase("image")) {

                        if(parser.getAttributeValue(null, "size").equals("extralarge"))
                        {
                            check=true;
                        }

                    }


                    break;

                case XmlPullParser.TEXT:
                    text = parser.getText();
                    break;

                case XmlPullParser.END_TAG:
                          String val = null; 
                         if  (tagname.equalsIgnoreCase("name")) {

                             val=text;
                             Log.i(""," name is "+val);

                         } 
                         else if (tagname.equalsIgnoreCase("mbid")) 
                         {

                             val=text;
                             Log.i(""," mbid is "+val);

                          } 
                         else if (tagname.equalsIgnoreCase("url")) 
                         {

                             val=text;
                             Log.i(""," url is "+val);

                          } 
                         else if (tagname.equalsIgnoreCase("image")) 
                         {

                             val=text;
                             if(check == true)
                             Log.i(""," image is "+val);

                          } 

                    break;

                default:
                    break;
                }
                eventType = parser.next();
            }

        } catch (XmlPullParserException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return null;
    }
}

The log

04-24 04:39:06.906: I/(1539):  name is Venom
04-24 04:39:06.906: I/(1539):  mbid is 5ddddef1-fd5a-4ca8-8e89-df4adff4239b
04-24 04:39:06.916: I/(1539):  url is Venom
04-24 04:39:06.916: I/(1539):  name is http://userserve-ak.last.fm/serve/252/35628151.png

Alternative Solution :

private TrackInfo readTrack(XmlPullParser parser) throws XmlPullParserException, IOException {
    parser.require(XmlPullParser.START_TAG, ns, "track");
    boolean nowPlaying = false;
    String artist = null;
    String artistPic = null;
    String artistMbid = null;
    String song = null;
    String songUrl = null;
    String album = null;
    String albumPic = null;
    int playedUts = 0;
    while (parser.next() != XmlPullParser.END_TAG) {
        if (parser.getEventType() != XmlPullParser.START_TAG) {
            continue;
        }
        String name = parser.getName();
        if (name.equals("artist")) {
            parser.require(XmlPullParser.START_TAG, ns, "artist");
            while (parser.next() != XmlPullParser.END_TAG) {
                if (parser.getEventType() != XmlPullParser.START_TAG) {
                    continue;
                }
                String artistName = parser.getName();
                if (artistName.equals("name")) {
                    artist = readArtist(parser);
                } else if (artistName.equals("mbid")) {
                    artistMbid = readArtistMbid(parser);
                } else if (artistName.equals("image")) {
                    boolean check = false;
                    String imagesize = parser.getAttributeValue(null, "size");
                    if (imagesize.equals("extralarge")) {
                        check = true;
                    }
                    if (check) {
                        artistPic = readArtistPic(parser);
                    } else {
                        parser.nextText();
                    }
                } else {
                    skip(parser);
                }
            }
        } else if (name.equals("name")) {
            song = readSong(parser);
        } else if (name.equals("url")) {
            songUrl = readSongUrl(parser);
        } else if (name.equals("album")) {
            album = readAlbum(parser);
        } else if (name.equals("date")) {
            playedUts = Integer.parseInt(readUts(parser));
        } else {
            skip(parser);
        }
    }
    return new TrackInfo(nowPlaying, artist, artistPic, artistMbid, song, songUrl,
            album, albumPic, playedUts);
}

...

private String readArtistPic(XmlPullParser parser) throws XmlPullParserException, IOException {
    parser.require(XmlPullParser.START_TAG, ns, "image");
    String artistPic = readText(parser);
    parser.require(XmlPullParser.END_TAG, ns, "image");
    return artistPic;
}

...
Sign up to request clarification or add additional context in comments.

5 Comments

Thanks for the example. I'm actually looking for something that can be added to the code I'm currently working on, and using your code would mean a complete rewrite, but maybe I can get som useful info out of it. I'll keep you posted!
@Daemun its no different. Its the same xml pull parser. It works the same way.
Got it! I'll post the answer in my original post. Thanks!
@Daemun you can edit my post and update if it really solved your problem
I didn't use your code (except for the 'check = true'), but it gave me a better understanding of the parsing-process. Thanks a lot!

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.