项目中要添加RSS源,显示RSS的所有文章,刚好测试的是新浪的新闻RSS源,各种百度之后,找到了这位前辈写的用SAXParser模式解析xml文件的代码,只要参考这个链接,绝对每个小白都可以轻松的解析基本上的RSS源,链接如下:SAXParser解析正常的RSS源例子,大概的流程就是根据xml的节点,先建立一个类,用来保存各个节点数据,然后写一个类继承DefaultHandler,重写那四个方法,将数据存入到list中,最后就是关键的一个功能代码,根据给出的URL正式解析,功能代码如下:
URL url = new URL(urlStr);
SAXParserFactory saxParserFactory = SAXParserFactory.newInstance(); // 构建SAX解析工厂
SAXParser saxParser = saxParserFactory.newSAXParser(); // 解析工厂生产解析器
XMLReader xmlReader = saxParser.getXMLReader(); // 通过saxParser构建xmlReader阅读器
RssHandler rssHandler = new RssHandler();
xmlReader.setContentHandler(rssHandler);
// 使用url打开流,并将流作为 xmlReader解析的输入源并解析
InputSource inputSource = new InputSource(url.openStream());
xmlReader.parse(inputSource);
return rssHandler.getRssFeed();
http://finance.sina.com.cn/
http://i1.sinaimg.cn/cj/pic/newLogo/logo_home_fin.gif
http://news.sina.com.cn/news1000/index.shtml?requestOrder=7
zh-cn
WWW.SINA.COM.CN
5
Fri, 11 Sep 2015 09:35:08 GMT
http://go.rss.sina.com.cn/redirect.php?url=http://finance.sina.com.cn/money/forex/20150911/173423224617.shtml
WWW.SINA.COM.CN
http://go.rss.sina.com.cn/redirect.php?url=http://finance.sina.com.cn/money/forex/20150911/173423224617.shtml
Fri, 11 Sep 2015 09:34:41 GMT
-
http://go.rss.sina.com.cn/redirect.php?url=http://finance.sina.com.cn/world/20150911/173223224593.shtml
WWW.SINA.COM.CN
http://go.rss.sina.com.cn/redirect.php?url=http://finance.sina.com.cn/world/20150911/173223224593.shtml
Fri, 11 Sep 2015 09:32:51 GMT
-
http://go.rss.sina.com.cn/redirect.php?url=http://finance.sina.com.cn/china/20150911/173123224590.shtml
WWW.SINA.COM.CN
http://go.rss.sina.com.cn/redirect.php?url=http://finance.sina.com.cn/china/20150911/173123224590.shtml
Fri, 11 Sep 2015 09:31:34 GMT
package client.verbank.mtp.allone.frame.ForeignNewsFragment.RSSUtil;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
public class RssHandler extends DefaultHandler {
RssFeed rssFeed = null;
RssItem rssItem = null;
String lastElementName = "";// 标记变量,用于标记在解析过程中我们关心的几个标签,若不是我们关心的标签记做0
final int RSS_TITLE = 1;// 若是 title 标签,记做1,注意有两个title,但我们都保存在item的成员变量中
final int RSS_LINK = 2;// 若是 link 标签,记做2
final int RSS_DESCRIPTION = 3;// 若是 description 标签,记做3
final int RSS_CATEGORY = 4;// 若是category标签,记做 4
final int RSS_PUBDATE = 5; // 若是pubdate标签,记做5,注意有两个pubdate,但我们都保存在item的pubdate成员变量中
int currentFlag = 0;
private StringBuilder sb = new StringBuilder();
@Override
public void startDocument() throws SAXException {
super.startDocument();
rssFeed = new RssFeed();
// rssItem = new RssItem();
}
@Override
public void characters(char[] ch, int start, int length)
throws SAXException {
super.characters(ch, start, length);
sb.append(ch, start, length);
}
@Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
super.startElement(uri, localName, qName, attributes);
sb.setLength(0);
if ("item".equals(localName)) {
rssItem = new RssItem();
}
}
@Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
super.endElement(uri, localName, qName);
String value = sb.toString();
// System.out.println(value + "value的值为");
// System.out.println(localName + "localName的值为");
if (rssItem == null) {
return;
}
if ("title".equals(localName)) {
rssItem.setTitle(value.trim());
} else if ("description".equals(localName)) {
rssItem.setDescription(value);
} else if ("link".equals(localName)) {
rssItem.setLink(value);
} else if ("pubDate".equals(localName)) {
rssItem.setPubdate(value);
} else if ("category".equals(localName)) {
rssItem.setCategory(value);
}
// 如果解析一个item节点结束,就将rssItem添加到rssFeed中。
if ("item".equals(localName)) {
rssFeed.addItem(rssItem);
}
}
@Override
public void endDocument() throws SAXException {
super.endDocument();
}
public RssFeed getRssFeed() {
return rssFeed;
}
}
这样就顺利的解决了xml文件中,开头不是正常的item节点,以及有些节点包含:的问题,成功解决!!!感谢同事的指导,一开始还没仔细看过新浪的RSSxml文件,以为代码有错误,后来才发现是没有对空指针的情况进行判断,希望有遇到同样问题的人有一点帮助。
=====================分割线2016年3月11日09:04:29,当需要解析总节点上的title和每个item的所有信息,使用以上解析的方法无法完成解析,而且需要同时解析多个rss源方法更新如下=====
代码如下:
public List getFeeds(String url) {
List feedList = new ArrayList();
String[] rssUrlVec = url.split(",");
for (String rss : rssUrlVec) {
RssFeed rssFeed = new RssFeed();
try {
URL rssUrl = new URL(rss);
XMLNode xmlNode = XMLCaptain.parseStream(rssUrl.openStream());
for (int i = 0; i < xmlNode.getSubNodeSize(); i++) {
XMLNode node = xmlNode.getSubNode(i);
if (node.getName().equalsIgnoreCase("channel")) {
for (int j = 0; j < node.getSubNodeSize(); j++) {
XMLNode channelNode = node.getSubNode(j);
if (channelNode.getName().equalsIgnoreCase("title")) {
rssFeed.setTitle(channelNode.getValue());
}
if (channelNode.getName().equalsIgnoreCase("item")) {
RssItem item = new RssItem();
for (int k = 0; k < channelNode
.getSubNodeSize(); k++) {
XMLNode itemNode = channelNode
.getSubNode(k);
if (itemNode.getName().equalsIgnoreCase(
"title")) {
item.setTitle(itemNode.getValue());
} else if (itemNode.getName()
.equalsIgnoreCase("link")) {
item.setLink(itemNode.getValue());
} else if (itemNode.getName()
.equalsIgnoreCase("pubdate")) {
item.setPubdate(itemNode.getValue());
} else if (itemNode.getName()
.equalsIgnoreCase("description")) {
item.setDescription(itemNode.getValue());
} else if (itemNode.getName()
.equalsIgnoreCase("category")) {
item.setCategory(itemNode.getValue());
}
}
rssFeed.addItem(item);
}
}
}
}
} catch (Exception e) {
continue;
}
feedList.add(rssFeed);
}
return feedList;
}