简体   繁体   中英

Parsing RSS xml feed with Retrofit

I am trying to parse an xml feed with Retrofit api but i was blocked , i don't know how to access to those attribues i think the problem is the Root Rss !

This is the feed : http://www.ka-news.de/storage/rss/rss/karlsruhe.xml

this is my code, Main activity where i will passe the data (list of item) to the adapter.

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    // TODO Auto-generated method stub      
    View rootView = inflater.inflate(R.layout.fragment_main, container, false);

    RestAdapter restAdapter = new RestAdapter.Builder()
            .setEndpoint("http://www.ka-news.de")
            .setConverter(new SimpleXmlConverter())
            .setLogLevel(RestAdapter.LogLevel.FULL)
            .build();

    api apiService = restAdapter.create(api.class);
    Rss rss = apiService.getRss();
    List<Item> items = rss.getChannel().getItemList();
    // Obtener el Recycler
    recycler = (RecyclerView) rootView.findViewById(R.id.reciclador);
    recycler.setHasFixedSize(true);

    // Usar un administrador para LinearLayout
    lManager = new LinearLayoutManager(getContext());
    recycler.setLayoutManager(lManager);

    // Crear un nuevo adaptador
    adapter = new AnimeAdapter(items);
    recycler.setAdapter(adapter);


    rootView.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.MATCH_PARENT ));       
    return rootView;        
}

api interface :

public interface api {
@GET("/storage/rss/rss/karlsruhe.xml")
public Rss getRss();
}

I have create three entities :

Channel :

@Root(strict = false)
public class Channel {
    @ElementList(name = "item", required = true, inline = true)
    public List<Item> itemList;

public List<Item> getItemList() {
    return itemList;
}

public void setItemList(List<Item> itemList) {
    this.itemList = itemList;
}

}

Item:

@Root(name = "item", strict = false)
public  class Item {
@Element(name = "title", required = true)
String title;
@Element(name = "link", required = true)
String link;
@Element(name = "description", required = true)
String description;
@Element(name = "pubDate", required = false)
String pubDate;


public String getTitle() {
    return title;
}

public void setTitle(String title) {
    this.title = title;
}

public String getLink() {
    return link;
}

public void setLink(String link) {
    this.link = link;
}

public String getDescription() {
    return description;
}

public void setDescription(String description) {
    this.description = description;
}

public String getPubDate() {
    return pubDate;
}

public void setPubDate(String pubDate) {
    this.pubDate = pubDate;
}

@Override
public String toString() {
    return "Item{" +
            "title='" + title + '\'' +
            ", link='" + link + '\'' +
            ", description='" + description + '\'' +
            ", pubDate='" + pubDate + '\'' +
            '}';
}

}

Rss:

@Root
public class Rss {

@Attribute
String version;

@Element
Channel channel;


public Channel getChannel() {
    return channel;
}

public String getVersion() {
    return version;
}

public void setVersion(String version) {
    this.version = version;
}

public void setChannel(Channel channel) {
    this.channel = channel;
}

@Override
public String toString() {
    return "RSS{" +
            "version='" + version + '\'' +
            ", channel=" + channel +
            '}';
}

}

the problem showing in log is :

FATAL EXCEPTION: main
retrofit.RetrofitError
at retrofit.RestAdapter$RestHandler.invokeRequest(RestAdapter.java:394)
at retrofit.RestAdapter$RestHandler.invoke(RestAdapter.java:240)
at $Proxy1.getRss(Native Method)
at br.liveo.ndrawer.ui.fragment.MainFragment.onCreateView(MainFragment.java:109)

this line :

Rss rss = apiService.getRss();

I have find the solution inspired from those post in stackoverflow.com: First link and Second link

have already create new api and entities :

The api interface :

public interface RssAdapter{
@GET("/storage/rss/rss/karlsruhe.xml")
void getItems(Callback<Feed> callback);
}

Feed class :

@Root(name = "rss", strict = false)
public class Feed implements Serializable {
@Element(name = "channel")
private Channel mChannel;

public Channel getmChannel() {
    return mChannel;
}

public Feed() {
}

public Feed(Channel mChannel) {
    this.mChannel = mChannel;
}
}

and channel class:

@Root(name = "channel", strict = false)
public class Channel implements Serializable {
@ElementList(inline = true, name="item")
private List<FeedItem> mFeedItems;

public List<FeedItem> getFeedItems() {
    return mFeedItems;
}

public Channel() {
}

public Channel(List<FeedItem> mFeedItems) {
    this.mFeedItems = mFeedItems;
}
}

and the last one it's item:

@Root(name = "item", strict = false)
public class FeedItem implements Serializable {
@Element(name = "pubDate")
private String mpubDate;
@Element(name = "title")
private String mtitle;
@Element(name = "link")
private String mlink;
@Element(name = "description")
private String mdescription;

public FeedItem() {
        }

public FeedItem(String mdescription, String mlink, String mtitle, String mpubDate) {
    this.mdescription = mdescription;
    this.mlink = mlink;
    this.mtitle = mtitle;
    this.mpubDate = mpubDate;
}

public String getMpubDate() {
    return mpubDate;
}

public void setMpubDate(String mpubDate) {
    this.mpubDate = mpubDate;
}

public String getMtitle() {
    return mtitle;
}

public void setMtitle(String mtitle) {
    this.mtitle = mtitle;
}

public String getMlink() {
    return mlink;
}

public void setMlink(String mlink) {
    this.mlink = mlink;
}

public String getMdescription() {
    return mdescription;
}

public void setMdescription(String mdescription) {
    this.mdescription = mdescription;
}
}

of course in my main activity i will put that :

RestAdapter restAdapter = new RestAdapter.Builder()
            .setEndpoint("http://www.ka-news.de")
            .setConverter(new SimpleXmlConverter())
            .build();

    RssAdapter rssAdapter = restAdapter.create(RssAdapter.class);
    rssAdapter.getItems(new Callback<Feed>() {
        @Override
        public void success(Feed newsitems, Response response) {
            Toast.makeText(getContext(), "oki", Toast.LENGTH_LONG).show();


            List<FeedItem> mItems = new ArrayList<>();

            mItems = newsitems.getmChannel().getFeedItems();
            // Crear un nuevo adaptador
            adapter = new AnimeAdapter(mItems);
            recycler.setAdapter(adapter);

        }

        @Override
        public void failure(RetrofitError error) {
            System.out.println(error);

            Toast.makeText(getContext(), "Error" + error.getMessage(),           Toast.LENGTH_LONG).show();


        }
    });

and the items getting from the parsing using the retrofit api i will set on the adapter constructor to show that in the listview or RecyclerView.

Good Luck

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM