Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
If you want to parse an RSS Feed using SimpleXML you can use this as an Start. I used this to parse RSS using RetroFit from Square
import org.simpleframework.xml.Attribute;
import org.simpleframework.xml.Element;
import org.simpleframework.xml.ElementList;
import org.simpleframework.xml.Namespace;
import org.simpleframework.xml.NamespaceList;
import org.simpleframework.xml.Root;
import org.simpleframework.xml.Text;
import java.util.List;
@NamespaceList({
@Namespace(reference = "http://www.w3.org/2005/Atom", prefix = "atom")
})
@Root(strict = false)
public class Channel {
// Tricky part in Simple XML because the link is named twice
@ElementList(entry = "link", inline = true, required = false)
public List<Link> links;
@ElementList(name = "item", required = true, inline = true)
public List<Item> itemList;
@Element
String title;
@Element
String language;
@Element(name = "ttl", required = false)
int ttl;
@Element(name = "pubDate", required = false)
String pubDate;
@Override
public String toString() {
return "Channel{" +
"links=" + links +
", itemList=" + itemList +
", title='" + title + '\'' +
", language='" + language + '\'' +
", ttl=" + ttl +
", pubDate='" + pubDate + '\'' +
'}';
}
public static class Link {
@Attribute(required = false)
public String href;
@Attribute(required = false)
public String rel;
@Attribute(name = "type", required = false)
public String contentType;
@Text(required = false)
public String link;
}
@Root(name = "item", strict = false)
public static class Item {
@Element(name = "title", required = true)
String title;//The title of the item. Venice Film Festival Tries to Quit Sinking
@Element(name = "link", required = true)
String link;//The URL of the item. http://www.nytimes.com/2002/09/07/movies/07FEST.html
@Element(name = "description", required = true)
String description;//The item synopsis. Some of the most heated chatter at the Venice Film Festival this week was about the way that the arrival of the stars at the Palazzo del Cinema was being staged.
@Element(name = "author", required = false)
String author;//Email address of the author of the item. More. oprah@oxygen.net
@Element(name = "category", required = false)
String category;//Includes the item in one or more categories. More. Simpsons Characters
@Element(name = "comments", required = false)
String comments;//URL of a page for comments relating to the item. More. http://www.myblog.org/cgi-local/mt/mt-comments.cgi?entry_id=290
@Element(name = "enclosure", required = false)
String enclosure;// Describes a media object that is attached to the item. More. <enclosure url="http://live.curry.com/mp3/celebritySCms.mp3" length="1069871" type="audio/mpeg"/>
@Element(name = "guid", required = false)
String guid;//A string that uniquely identifies the item. More. <guid isPermaLink="true">http://inessential.com/2002/09/01.php#a2</guid>
@Element(name = "pubDate", required = false)
String pubDate;// Indicates when the item was published. More. Sun, 19 May 2002 15:21:36 GMT
@Element(name = "source", required = false)
String source;// The RSS channel that the item came from. More.
@Override
public String toString() {
return "Item{" +
"title='" + title + '\'' +
", link='" + link + '\'' +
", description='" + description + '\'' +
", author='" + author + '\'' +
", category='" + category + '\'' +
", comments='" + comments + '\'' +
", enclosure='" + enclosure + '\'' +
", guid='" + guid + '\'' +
", pubDate='" + pubDate + '\'' +
", source='" + source + '\'' +
'}';
}
}
}
public static <T> T createXmlAdapterFor(final Class<T> api, final String endpoint, final Client client) {
Preconditions.checkNotNull(client);
Preconditions.checkNotNull(endpoint);
//
final RestAdapter.LogLevel level = getLogLevel();
Log.d(LOG_TAG, "Log Level:" + level);
final RestAdapter adapter = new RestAdapter.Builder()//
.setEndpoint(endpoint)//
.setConverter(new SimpleXMLConverter())//
.setClient(client)//
.setLogLevel(level)//
.build();
//
return adapter.create(api);
}
import org.simpleframework.xml.Attribute;
import org.simpleframework.xml.Element;
import org.simpleframework.xml.Root;
@Root
public class RSS {
@Attribute
String version;
@Element
Channel channel;
public Channel getChannel() {
return channel;
}
@Override
public String toString() {
return "RSS{" +
"version='" + version + '\'' +
", channel=" + channel +
'}';
}
}
final String baseURL = getString(YOU_ENDPOINT_URL);
final Client client = RestAdapterUtil.createOKClient();
endpoint = RestAdapterUtil.createXmlAdapterFor(Endpoint.class, baseURL, client);
final Observable<RSS> events = endpoint.getRSSFeed();
@ariedov

This comment has been minimized.

Copy link

@ariedov ariedov commented Apr 16, 2015

You saved my day. Thank you! =)

@Jawnnypoo

This comment has been minimized.

Copy link

@Jawnnypoo Jawnnypoo commented Sep 11, 2015

Nice! Be careful with using this with Proguard though, since all the of fields do not specify "name" directly. Other than that, its great!

@Nuruddinjr

This comment has been minimized.

Copy link

@Nuruddinjr Nuruddinjr commented Jan 22, 2016

I am sorry for dumb question, how did you get endpoint.getRSSFeed()?

@indywidualny

This comment has been minimized.

Copy link

@indywidualny indywidualny commented Feb 21, 2016

Oh, great! I was thinking of writing it on my own right now but you did a pretty nice job here.
@Jawnnypoo I don't know whether it's a good practice but I always exclude models from Proguard. It's a way to avoid problems.

@hossain-khan

This comment has been minimized.

Copy link

@hossain-khan hossain-khan commented Oct 15, 2016

Here is example using Retrofit2 if anybody is wondering...

    public static <T> T createXmlAdapterFor(final Class<T> api, final String endpoint) {
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(endpoint)
                .client(new OkHttpClient()) // Use OkHttp3 client
                .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) // RxJava adapter
                .addConverterFactory(SimpleXmlConverterFactory.create()) // Simple XML converter
                .build();
        return retrofit.create(api);
    }

And the retrofit 2 service API

public interface RssFeedService {
    /**
     * Provides RSS feed data.
     * @param feedUrl RSS Feed URL. Note: This must be fully qualified URL.
     * @return RSS Feed
     */
    @GET
    Observable<RSS> getFeed(@Url String feedUrl);
}

And finally call with retrofit

        RssFeedService xmlAdapterFor = ApiService.createXmlAdapterFor(RssFeedService.class, "http://www.thestar.com/");
        Observable<RSS> rssObservable = xmlAdapterFor.getFeed("http://www.thestar.com/feeds.topstories.rss");
        rssObservable.subscribe(new Subscriber<RSS>() {
            @Override
            public void onCompleted() {
                Log.d(TAG, "onCompleted() called");
            }

            @Override
            public void onError(final Throwable e) {
                Log.d(TAG, "onError() called with: e = [" + e + "]");
            }

            @Override
            public void onNext(final RSS rss) {
                Log.d(TAG, "onNext() called with: rss = [" + rss + "]");
            }
        });

And here is my gradle dependency for retrofit

    // Retrofit - retrofitVersion = '2.1.0'
    compile "com.squareup.retrofit2:retrofit:$rootProject.retrofitVersion"
    compile "com.squareup.retrofit2:converter-gson:$rootProject.retrofitVersion"
    compile "com.squareup.retrofit2:converter-scalars:$rootProject.retrofitVersion"
    compile ("com.squareup.retrofit2:converter-simplexml:$rootProject.retrofitVersion") {
        // https://github.com/square/retrofit/tree/master/retrofit-converters/simplexml
        // exclude the following transitive dependencies: stax:stax-api, stax:stax, and xpp3:xpp3
        exclude group: 'xpp3', module: 'xpp3'
        exclude group: 'stax', module: 'stax-api'
        exclude group: 'stax', module: 'stax'
    }
    compile "com.squareup.retrofit2:adapter-rxjava:$rootProject.retrofitVersion"
@dpedroza

This comment has been minimized.

Copy link

@dpedroza dpedroza commented Dec 5, 2016

It helped a lot, thanks!

@crazyhitty

This comment has been minimized.

Copy link

@crazyhitty crazyhitty commented Feb 16, 2017

Thank you very much for this!

@faruktoptas

This comment has been minimized.

Copy link

@faruktoptas faruktoptas commented Mar 3, 2017

It helped me thanks

@faruktoptas

This comment has been minimized.

@tschuchortdev

This comment has been minimized.

Copy link

@tschuchortdev tschuchortdev commented Aug 10, 2017

@macsystems I have added fields for the popular rss content module. Maybe they will be useful for other people as well and you might want to add them here (since PRs are not possible for gists)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment