I have a rss feed reader application. The goal is to store the title and image for each item in a custom object named RSSItem, and oll the RSSItem objects in another object named RSSFeed. The problem is that if an item element does not have an enclosure element SaxException is thrown. How should I handle the errors with this parser? Here is the parser code:
public class Parser {
private final String RSS_ELEMENT = "rss";
private final String CHANNEL_ELEMENT = "channel";
private final String ITEM_ELEMENT = "item";
private final String ENCLOSURE_ELEMENT = "enclosure";
private final String TITLE_ELEMENT = "title";
private final String URL_ATTRIBUTE = "url";
private final String TYPE_ATTRIBUTE = "type";
private final String IMAGE_TYPE = "image/jpeg";
RSSItem rssItem;
RSSFeed rssFeed;
final URL mFeedUrl;
public Parser(String feedUrl) {
try {
mFeedUrl = new URL(feedUrl);
} catch (MalformedURLException e) {
Log.e(e.getClass().getSimpleName(), e.getMessage());
throw new RuntimeException(e);
}
rssFeed = new RSSFeed();
}
protected InputStream getInputStream() {
try {
return mFeedUrl.openConnection().getInputStream();
} catch (IOException e) {
Log.e(e.getClass().getSimpleName(), e.getMessage());
return null;
}
}
public RSSFeed parse() {
InputStream istream = getInputStream();
RootElement root = new RootElement(R开发者_如何转开发SS_ELEMENT);
Element channel = root.requireChild(CHANNEL_ELEMENT);
Element itemElement = channel.requireChild(ITEM_ELEMENT);
Element enclosure = itemElement.requireChild(ENCLOSURE_ELEMENT);
Element title = itemElement.requireChild(TITLE_ELEMENT);
enclosure.setStartElementListener(new StartElementListener() {
public void start(Attributes attrs) {
String imageType = attrs.getValue(TYPE_ATTRIBUTE);
if (imageType.equals(IMAGE_TYPE)) {
try {
String imageUrl = attrs.getValue(URL_ATTRIBUTE);
Bitmap bitmap = BitmapFactory.decodeStream((InputStream)new URL(imageUrl).getContent());
rssItem.setImage(bitmap);
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
});
title.setEndTextElementListener(new EndTextElementListener() {
public void end(String body) {
rssItem.setTitle(body);
}
});
itemElement.setStartElementListener(new StartElementListener() {
public void start(Attributes arg0) {
rssItem = new RSSItem();
}
});
itemElement.setEndElementListener(new EndElementListener() {
public void end() {
rssFeed.addItem(rssItem);
}
});
try {
Xml.parse(istream, Xml.Encoding.UTF_8, root.getContentHandler());
} catch (Exception e) {
e.printStackTrace();
}
return rssFeed;
}
}
I would not recommend trying to implement your own RSS parser , but rather using a standard library for that.
It's fairly easy to setup an implementation of a SAX parser but the hard part is to be able to parse any and every feed under the sun.
You need to cater to all formats RSS 1, RSS 2, Atom etc. Even then you will have to contend with poorly formatted feeds.
I had faced similar problems in the past so decided to do my feed parsing on a server and just get the parsed contents. This allows me to run more complex libraries and parser which I can modify without pushing out updates for my app.
I have the following service running on AppEngine which allows for a much simpler XML / JSON parsing at your end. There is a fixed and simple structure to the response. You can use this for parsing
http://evecal.appspot.com/feedParser
You can send both POST and GET requests with the following parameters.
feedLink : The URL of the RSS feed response : JSON or XML as the response format
Examples:
For a POST request
curl --data-urlencode "feedLink=http://feeds.bbci.co.uk/news/world/rss.xml" --data-urlencode "response=json" http://evecal.appspot.com/feedParser
For GET request
evecal.appspot.com/feedParser?feedLink=http://feeds.nytimes.com/nyt/rss/HomePage&response=xml
My android app "NewsSpeak" uses this too.
精彩评论