Search code examples
androidrsscdata

CDATA not parsed for ANDROID RSS reader


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

   }

Solution

  • 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. ;)