0

I'm working on an ANDROID app that reads RSS feeds so I used this tutorial ( http://android-er.blogspot.com/2010/05/simple-rss-reader-ii-implement-with.html )/ source code available here, and implemented it to my own url rss feeder. But the description tag isn't being shown..mostly cz in the xml of the feeder the description tags are CDATA. how can i parse the description cdata in my rss??Thanks!

this is my handler code:

import org.xml.sax.Attributes;
 import org.xml.sax.SAXException;
 import org.xml.sax.helpers.DefaultHandler;

public class RSSHandler extends DefaultHandler {

final int state_unknown = 0;
final int state_title = 1;
final int state_description = 2;
final int state_link = 3;
final int state_pubdate = 4;
int currentState = state_unknown;

RSSFeed feed;
RSSItem item;

boolean itemFound = false;

RSSHandler(){
}

RSSFeed getFeed(){
    return feed;
}

@Override
public void startDocument() throws SAXException {
    // TODO Auto-generated method stub
    feed = new RSSFeed();
    item = new RSSItem();

}

@Override
public void endDocument() throws SAXException {
    // TODO Auto-generated method stub
}

@Override
public void startElement(String uri, String localName, String qName,
        Attributes attributes) throws SAXException {
    // TODO Auto-generated method stub

    if (localName.equalsIgnoreCase("item")){
        itemFound = true;
        item = new RSSItem();
        currentState = state_unknown;
    }
    else if (localName.equalsIgnoreCase("title")){
        currentState = state_title;
    }
    else if (localName.equalsIgnoreCase("description")){
        currentState = state_description;
    }
    else if (localName.equalsIgnoreCase("link")){
        currentState = state_link;
    }
    else if (localName.equalsIgnoreCase("pubdate")){
        currentState = state_pubdate;
    }
    else{
        currentState = state_unknown;
    }

}

@Override
public void endElement(String uri, String localName, String qName)
        throws SAXException {
    // TODO Auto-generated method stub
    if (localName.equalsIgnoreCase("item")){
        feed.addItem(item);
    }
}

@Override
public void characters(char[] ch, int start, int length)
        throws SAXException {
    // TODO Auto-generated method stub

    String strCharacters = new String(ch,start,length);

    if (itemFound==true){
    // "item" tag found, it's item's parameter
        switch(currentState){
        case state_title:
            item.setTitle(strCharacters);
            break;
        case state_description:
            item.setDescription(strCharacters);
            break;
        case state_link:
            item.setLink(strCharacters);
            break;
        case state_pubdate:
            item.setPubdate(strCharacters);
            break;  
        default:
            break;
        }
    }
    else{
    // not "item" tag found, it's feed's parameter
        switch(currentState){
        case state_title:
            feed.setTitle(strCharacters);
            break;
        case state_description:
            feed.setDescription(strCharacters);
            break;
        case state_link:
            feed.setLink(strCharacters);
            break;
        case state_pubdate:
            feed.setPubdate(strCharacters);
            break;  
        default:
            break;
        }
    }

    currentState = state_unknown;
}


  }

RSSFeed :

 import java.util.List;
 import java.util.Vector;

 public class RSSFeed {
   private String title = null;
   private String description = null;
   private String link = null;
   private String pubdate = null;
   private List<RSSItem> itemList;

RSSFeed(){
    itemList = new Vector<RSSItem>(0);
}

void addItem(RSSItem item){
    itemList.add(item);
}

RSSItem getItem(int location){
    return itemList.get(location);
}

List<RSSItem> getList(){
    return itemList;
}

void setTitle(String value)
{
    title = value;
}
void setDescription(String value)
{
    description = value;
}
void setLink(String value)
{
    link = value;
}
void setPubdate(String value)
{
    pubdate = value;
}

String getTitle()
{
    return title;
}
String getDescription()
{
    return description;
}
String getLink()
{
    return link;
}
String getPubdate()
{
    return pubdate;
}

   }
Beast
  • 135
  • 1
  • 11
  • Can you provide the handler? I've done this few days ago (probably with the same tutorial) and it's working. – Enrichman Aug 01 '12 at 13:07
  • I just added my handler code :) – Beast Aug 01 '12 at 13:18
  • Thanks. Try to implement mine, doing some little modification to store also the feed parameters. Everytime I see a Handler the logic is inside the characters method (should be in the endElement one). This is simply wrong. I should do a tutorial on my site! lol – Enrichman Aug 01 '12 at 13:21
  • Sir im stuck with this error: The method setLink(String) in the type RSSItem is not applicable for the arguments (URL) – Beast Aug 01 '12 at 13:47
  • Just remove the url conversion and pass to setLink a string. -> else if (localName.equals("link") && inItem) { item.setLink(value); } – Enrichman Aug 01 '12 at 13:52
  • I ADDED :RSSFeed feed; RSSHandler(){ } RSSFeed getFeed(){ return feed; } in my handler so i can use myRssFeed = myRSSHandler.getfeed(); in my RSSREADER BUT WHEN I OPEND THE APP IT SAID: NO DATA :s – Beast Aug 01 '12 at 14:07
  • Hard to answer where is the problem. Try to debug putting a breakpoint in your handler. :| – Enrichman Aug 01 '12 at 14:10
  • You're welcome! If my answer didn't resolved your problem you don't have to accept, but if you find it useful +1 it (if you can! I don't remember the reputation needed). :) – Enrichman Aug 01 '12 at 14:32
  • Sir my problem in displaying cdata was solved thanks to u..but now im having trouble displaying the whole. can You post your main activity code..cause in mine i used to call the getfeed fonction now i should call the getrss since You added your items in rss not in feed which was my case – Beast Aug 02 '12 at 07:13

2 Answers2

1

That's how I did:

public class RssHandler extends DefaultHandler {

private RssItem item;
private RssFeed feed;
private boolean inItem;

private String value;
private StringBuffer buffer;

@Override
public void startElement(
        String nameSpaceURI,
        String localName,
        String qName,
        Attributes atts
) {

    buffer = new StringBuffer();

    if (localName.equals("channel")) {
        feed = new RssFeed();
        inItem = false;
    } else if (localName.equals("item")) {
        item = new RssItem();
        inItem = true;
    }
}

public void endElement(
        String uri,
        String localName,
        String qName) {

    value = buffer.toString();
    buffer.setLength(0);

    value = Html.fromHtml(value).toString();

    if (localName.equals("pubDate") && !inItem) {
        feed.setPublishedDate(value);
    } else if (localName.equals("title") && !inItem) {
        feed.setTitle(value);
    } else if (localName.equals("link") && !inItem) {
        URL url = null;
        try {
            url = new URL(value);
        } catch (MalformedURLException e) {
            Log.e("ERR", "error while creating url from [" + value + "]");
        }
        if (url != null) {
            feed.setLink(url);
        }
    } else if (localName.equals("description") && !inItem) {
        feed.setDescription(value);
    } else if (localName.equals("pubDate") && inItem) {
        item.setPublishedDate(value);
    } else if (localName.equals("title") && inItem) {
        item.setTitle(value);
    } else if (localName.equals("link") && inItem) {
        URL url = null;
        try {
            url = new URL(value);
        } catch (MalformedURLException e) {
            Log.e("ERR", "error while creating url from [" + value + "]");
        }
        if (url != null) {
            item.setLink(url);
        }
    } else if (localName.equals("description") && inItem) {
        item.setDescription(value);
    } else if (localName.equals("item")) {
        feed.addItem(item);
        inItem = false;
    }
}

public void characters(char[] ch, int start, int end) {
    buffer.append(new String(ch, start, end));
}

public ArrayList<RssItem> getRss() {
    return this.rss;
}
}

Hope this help. : )

EDIT:

I've edited my answer to match with your feed. Should work. Don't forget to accept the answer if everythings is ok. ;)

Enrichman
  • 11,157
  • 11
  • 67
  • 101
  • sir can you plz send me Your RSSReader class? – Beast Aug 05 '12 at 22:39
  • Sorry man, I was on holiday! Btw I'm going to make my application public, if you still need it I can share it. : ) – Enrichman Aug 13 '12 at 10:43
  • Hope You had fun! :) ..I would love it if you share please! Thank you a lot Sir – Beast Aug 14 '12 at 01:01
  • I've to wait till thursday to share it (copyright issues). In the meanwhile we can try to adapt your code, instead of mine. Can you share the RSSFeed class? I will edit my answer to produce an RSSFeed instead of a Collection (it's probably something that you could do, btw). ;) – Enrichman Aug 14 '12 at 07:42
  • Oh yes, here you are: https://github.com/enrichman/roma-tre. But probably is easier to modify your handler and produce an RSSFeed! : ) – Enrichman Aug 17 '12 at 08:20
  • I've edited the answer to match the feed. Accept if it's ok. :) – Enrichman Aug 21 '12 at 07:40
0

Instead of using Html.fromHtml() use org.apache.commons.lang.StringEscapeUtils's unescapeHtml().

Please see this discussion Is there a faster way to decode html characters to a string than Html.fromHtml()?

Community
  • 1
  • 1
takesavy
  • 135
  • 2
  • 16