I am trying to parse an XML feed with Retrofit API but I was blocked, I don't know how to access those attributes I think the problem is the Root RSS!
This is the feed : http://www.ka-news.de/storage/rss/rss/karlsruhe.xml
The main activity is where I will pass the data (list of items) 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 created 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