Reputation: 1885
I'm creating a small app to read in the BBC f1 news feed into android and to display in a ListView
. I have created the below parsing functions by following this Android Developer Tutorial.
When the items ArrayList
is returned to the activity it only has one item, the most recent news story. When I log the
These functions are called after successfully retrieving the data via a async call. On the second to last line the output title is the same as the returned array item.
I have posted the logcat output to pastebin here
RSS Structure
<rss xmlns:media="http://search.yahoo.com/mrss/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0">
<channel>
// unrequired tags (title, description, lang etc)
<item>
<title></title>
<description></description>
<link></link>
<guid isPermaLink="false"></guid>
<pubDate></pubDate>
<media:thumbnail />
<media:thumbnail />
</item>
<item>
<title></title>
<description></description>
<link></link>
<guid isPermaLink="false"></guid>
<pubDate></pubDate>
<media:thumbnail />
<media:thumbnail />
</item>
</channel>
</rss>
read feed function
private static ArrayList<BBCItem> readFeed(XmlPullParser parser) throws XmlPullParserException, IOException {
//Log.d("read feed", "");
ArrayList<BBCItem> items = new ArrayList();
parser.require(XmlPullParser.START_TAG, ns, "rss");
while (parser.next() != XmlPullParser.END_TAG) {
if (parser.getEventType() != XmlPullParser.START_TAG) {
continue;
}
String name = parser.getName();
// Starts by looking for the channel tag
if (name.equals("channel")) {
// navigate to the item tag here
parser.require(XmlPullParser.START_TAG, ns, "channel");
while (parser.next() != XmlPullParser.END_TAG){
if (parser.getEventType() != XmlPullParser.START_TAG) {
continue;
}
name = parser.getName();
if (name.equals("item")){
items.add(bbcReadEntry(parser));
}
else {
skip(parser);
}
}
} else {
skip(parser);
}
}
return items;
}
read individual feed item
public static BBCItem bbcReadEntry(XmlPullParser parser) throws XmlPullParserException, IOException {
parser.require(XmlPullParser.START_TAG, ns, "item");
String title = null;
String description = null;
String url = null;
String pubDate = null;
String thumbnailURL = null;
while (parser.next() != XmlPullParser.END_TAG) {
if (parser.getEventType() != XmlPullParser.START_TAG) {
continue;
}
String name = parser.getName();
if (name.equals("title")) {
title = readString(parser, "title");
} else if (name.equals("description")) {
description = readString(parser, "description");
} else if (name.equals("link")) {
url = readString(parser, "link");
} else if (name.equals("pubDate")) {
pubDate = readString(parser, "pubDate");
} else if (name.equals("media:thumbnail")) {
//thumbnailURL = readThumbnail(parser);
thumbnailURL = "http://news.bbcimg.co.uk/media/images/81615000/jpg/_81615988_nicorosberg.jpg";
}
else {
skip(parser);
}
}
Log.d("News item title", title);
return new BBCItem(title, description, url, pubDate, thumbnailURL);
}
Any help much appreciated
Thanks
Upvotes: 0
Views: 1237
Reputation: 11
Ok, I have just had a similar issue when trying to parse the Scientific American technology RSS feed. In the Android developers document, the readFeed() method looks like:
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 entry tag
if (name.equals("entry")) {
entries.add(readEntry(parser));
} else {
skip(parser);
}
}
return entries;}
The reason why my code only sends back the first item in the RSS feed is because (after logging the entry in the line "entries.add(readEntry(parser));", it gets to the end of the RSS item entry and hits the line:
while (parser.next() != XmlPullParser.END_TAG) {
This in effect terminates the RSS parsing, and you then hit the "return entries;" line which returns the entries ArrayList with one item in.
To fix it (at least it worked for me), just amend the "END_TAG" to "END_DOCUMENT" and it works perfectly.
while (parser.next() != XmlPullParser.END_DOCUMENT) {
I just hope this helps someone, as I have been faffing about with this all day :-) Good luck with the XML parsing.
Upvotes: 1
Reputation: 3670
I ran into almost identical issue when working on something here. I was trying to parse the xml in a rss feed xml file. Same thing happened that i only got the first "item". I was also considering to convert the xml to json and more easily handle it as a json. But i finally managed to make it work for me with the xml file without converstsion to json. What goes wrong here is links that do not have a END_TAG like in my case this caused the problem:
<enclosure url="http:/blabla....mp3" length="123456" type="audio/mpeg" />
In your case this might cause same issue:
<media:thumbnail />
After following this google documentation page https://developer.android.com/training/basics/network-ops/xml.html , lots of testing and head scratching i resolved the issue by after getting the "url" attribute, calling the method "skip(parser)" directly after getting the "url" attribute value. That single line fixed the issue for my part. I am assuming that the parser then steps out of that TAG and continues with the remaining ones. Hope its of some help.
Upvotes: 1
Reputation: 1885
I never managed to get this working full. Instead I converted the XML string to JSON and manipulated that (which I'm much more comfortable with).
This answer is how I converted it from XML to JSON.
Upvotes: 0