处理rss解析器的错误

时间:2011-01-19 07:30:09

标签: android

我有一个RSS订阅源应用程序。目标是将每个项目的标题和图像存储在名为RSSItem的自定义对象中,并将RSSItem对象存储在另一个名为RSSFeed的对象中。问题是如果item元素没有enclosure元素,则抛出SaxException。我该如何处理这个解析器的错误?这是解析器代码:

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

1 个答案:

答案 0 :(得分:0)

我不建议尝试实现自己的RSS解析器,而是使用标准库。

设置SAX解析器的实现相当容易,但困难的部分是能够在太阳下解析任何和每个Feed。

您需要迎合所有格式RSS 1,RSS 2,Atom等。即使这样,您也必须应对格式不佳的Feed。

我过去遇到过类似的问题所以决定在服务器上进行feed解析,然后获取解析后的内容。这允许我运行更复杂的库和解析器,我可以在不推送应用程序更新的情况下进行修改。

我在AppEngine上运行了以下服务,它允许在您的末尾进行更简单的XML / JSON解析。响应有一个固定而简单的结构。您可以使用它来解析

http://evecal.appspot.com/feedParser

您可以使用以下参数发送POST和GET请求。

feedLink:RSS提要响应的URL:JSON或XML作为响应格式

示例:

对于POST请求

curl --data-urlencode“feedLink = http://feeds.bbci.co.uk/news/world/rss.xml”--data-urlencode“response = json”http://evecal.appspot.com/feedParser

对于GET请求

evecal.appspot.com/feedParser?feedLink=http://feeds.nytimes.com/nyt/rss/HomePage&response=xml

我的Android应用程序“NewsSpeak”也使用它。