While using XML DOM functionality in apex to read Rss Feed from external website I am facing the "Attempt to de-reference a null object"
. As I am new to salesforce I am not understanding where I am making mistake.
Added URL "http://feeds.abcnews.com/abcnews/topstories"
in Remote Site Settings
Here is my code :
Class :
public class RSS1 {
public class channel {
public String title {get;set;}
public String link {get;set;}
public String description {get;set;}
public String author {get;set;}
public String category {get;set;}
public String copyright {get;set;}
public String docs {get;set;}
public RSS.image image {get;set;}
public list<RSS.item> items {get;set;}
public channel() {
items = new list<RSS.item>();
}
}
public class image {
public String url {get;set;}
public String title {get;set;}
public String link {get;set;}
}
public class item {
public String title {get;set;}
public String guid {get;set;}
public String link {get;set;}
public String description {get;set;}
public String pubDate {get;set;}
public String source {get;set;}
public Date getPublishedDate() {
Date result = (pubDate != null) ? Date.valueOf(pubDate.replace('T', ' ').replace('Z','')) : null;
return result;
}
public DateTime getPublishedDateTime() {
DateTime result = (pubDate != null) ? DateTime.valueOf(pubDate.replace('T', ' ').replace('Z','')) : null;
return result;
}
}
public static RSS.channel getRSSData(string feedURL) {
HttpRequest req = new HttpRequest();
req.setEndpoint(feedURL);
req.setMethod('GET');
Dom.Document doc = new Dom.Document();
Http h = new Http();
/* if (!Test.isRunningTest()){
HttpResponse res = h.send(req);
doc = res.getBodyDocument();
} else {
String xmlString = '<?xml version="1.0" encoding="utf-8" ?><rss version="2.0" xmlns:os="http://a9.com/-/spec/opensearch/1.1/"><channel><title>salesforce.com - Bing News</title><link>http://www.bing.com/news</link><description>Search Results for salesforce.com at Bing.com</description><category>News</category><os:totalResults>3370</os:totalResults><os:startIndex>0</os:startIndex><os:itemsPerPage>10</os:itemsPerPage><os:Query role="request" searchTerms="salesforce.com" /><copyright>These XML results may not be used, reproduced or transmitted in any manner or for any purpose other than rendering Bing results within an RSS aggregator for your personal, non-commercial use. Any other use requires written permission from Microsoft Corporation. By using these results in any manner whatsoever, you agree to be bound by the foregoing restrictions.</copyright><image><url>http://www.bing.com/s/a/rsslogo.gif</url><title>Bing</title><link>http://www.bing.com/news</link></image><docs>http://www.rssboard.org/rss-specification</docs><item><title>Salesforce.com Makes Friends With CIOs - Information Week</title><guid>http://informationweek.com/news/cloud-computing/software/232602782</guid><link>http://informationweek.com/news/cloud-computing/software/232602782</link><description>Parade of CIOs at CloudForce shows how social networking inroads are making Salesforce.com a larger part of the IT infrastructure. Salesforce.com isn't just for sales forces anymore. Its Chatter app has opened a social networking avenue into the enterprise ...</description><pubDate>2012-03-19T15:21:47Z</pubDate><source>Information Week</source></item></channel></rss>';
doc.load(xmlString);
}*/
Dom.XMLNode rss = doc.getRootElement();
//first child element of rss feed is always channel
Dom.XMLNode channel = rss.getChildElements()[0];
RSS.channel result = new RSS.channel();
list<RSS.item> rssItems = new list<RSS.item>();
//for each node inside channel
for(Dom.XMLNode elements : channel.getChildElements()) {
if('title' == elements.getName()) {
result.title = elements.getText();
}
if('link' == elements.getName()) {
result.link = elements.getText();
}
if('description' == elements.getName()) {
result.description = elements.getText();
}
if('category' == elements.getName()) {
result.category = elements.getText();
}
if('copyright' == elements.getName()) {
result.copyright = elements.getText();
}
if('docs' == elements.getName()) {
result.docs = elements.getText();
}
if('image' == elements.getName()) {
RSS.image img = new RSS.image();
//for each node inside image
for(Dom.XMLNode xmlImage : elements.getChildElements()) {
if('url' == xmlImage.getName()) {
img.url = xmlImage.getText();
}
if('title' == xmlImage.getName()) {
img.title = xmlImage.getText();
}
if('link' == xmlImage.getName()) {
img.link = xmlImage.getText();
}
}
result.image = img;
}
if('item' == elements.getName()) {
RSS.item rssItem = new RSS.item();
//for each node inside item
for(Dom.XMLNode xmlItem : elements.getChildElements()) {
if('title' == xmlItem.getName()) {
rssItem.title = xmlItem.getText();
}
if('guid' == xmlItem.getName()) {
rssItem.guid = xmlItem.getText();
}
if('link' == xmlItem.getName()) {
rssItem.link = xmlItem.getText();
}
if('description' == xmlItem.getName()) {
rssItem.description = xmlItem.getText();
}
if('pubDate' == xmlItem.getName()) {
rssItem.pubDate = xmlItem.getText();
}
if('source' == xmlItem.getName()) {
rssItem.source = xmlItem.getText();
}
}
//for each item, add to rssItem list
rssItems.add(rssItem);
}
}
//finish RSS.channel object by adding the list of all rss items
result.items = rssItems;
return result;
}
/* static testMethod void RSSTest() {
RSS.channel chan = RSS.getRSSData('test');
Date pDate = chan.items[0].getPublishedDate();
DateTime pDateTime = chan.items[0].getPublishedDateTime();
} */
}
VF Page :
<apex:page controller="RSSNewsReader1" sidebar="false" showHeader="false" cache="false">
<apex:pageBlock id="rssBlock" tabStyle="Lead">
<apex:form style="padding-bottom: 10px;">
<span>Bing News Query (Enter a Topic): </span>
<apex:inputText value="{!rssQuery}" />
<apex:commandButton value="Search Bing News" reRender="rssBlock" status="searchStatus" />
<apex:actionStatus id="searchStatus" startStyleClass="ajax-loader" />
</apex:form>
<apex:pageBlockSection title="Channel" columns="2">
<apex:pageBlockSectionItem >
<apex:outputLabel value="title" />
<apex:outputText value="{!RSSFeed.title}" />
</apex:pageBlockSectionItem>
<apex:pageBlockSectionItem >
<apex:outputLabel value="link" />
<apex:outputText value="{!RSSFeed.link}" />
</apex:pageBlockSectionItem>
<apex:pageBlockSectionItem >
<apex:outputLabel value="description" />
<apex:outputText value="{!RSSFeed.description}" />
</apex:pageBlockSectionItem>
<apex:pageBlockSectionItem >
<apex:outputLabel value="category" />
<apex:outputText value="{!RSSFeed.category}" />
</apex:pageBlockSectionItem>
<apex:pageBlockSectionItem >
<apex:outputLabel value="docs" />
<apex:outputText value="{!RSSFeed.docs}" />
</apex:pageBlockSectionItem>
</apex:pageBlockSection>
<apex:pageBlockSection columns="1">
<apex:pageBlockSectionItem >
<apex:outputLabel value="copyright" />
<apex:outputText value="{!RSSFeed.copyright}" />
</apex:pageBlockSectionItem>
</apex:pageBlockSection>
<apex:pageBlockSection title="Image" columns="2">
<apex:pageBlockSectionItem >
<apex:outputLabel value="title" />
<apex:outputText value="{!RSSFeed.image.title}" />
</apex:pageBlockSectionItem>
<apex:pageBlockSectionItem >
<apex:outputLabel value="url" />
<apex:outputText value="{!RSSFeed.image.url}" />
</apex:pageBlockSectionItem>
<apex:pageBlockSectionItem >
<apex:outputLabel value="link" />
<apex:outputText value="{!RSSFeed.image.link}" />
</apex:pageBlockSectionItem>
<apex:pageBlockSectionItem >
<apex:outputLabel value="url image" />
<apex:image value="{!RSSFeed.image.url}" />
</apex:pageBlockSectionItem>
</apex:pageBlockSection>
<apex:pageBlockSection title="Items" columns="1">
<apex:pageBlockTable value="{!RSSFeed.items}" var="i">
<apex:column headerValue="title">
<apex:outputLink value="{!i.link}" target="_blank">{!i.title}</apex:outputLink>
</apex:column>
<apex:column headerValue="description" value="{!i.description}"/>
<apex:column headerValue="pubDate" style="width: 140px;">
<apex:outputText value="{0,date,MM/dd/yy h:mm:ss a}" >
<apex:param value="{!i.PublishedDateTime}" />
</apex:outputText>
</apex:column>
<apex:column headerValue="source" value="{!i.source}" style="width: 140px;" />
</apex:pageBlockTable>
</apex:pageBlockSection>
</apex:pageBlock>
</apex:page>
Controller:
public class RSSNewsReader1 {
public String rssQuery {get;set;}
private String rssURL {get;set;}
public RSSNewsReader1() {
rssURL = 'http://feeds.abcnews.com/abcnews/topstories';
}
public RSS.channel getRSSFeed() {
return RSS1.getRSSData(rssURL);
}
}