So, Today i will show you exactly how to parse from a XML or RSS that is on a third-party site.
Parsing from a xml or RSS is the same thing, you need only to modify the extension .xml or .rss.
First of all you will need some files that you will add in your project and leave them intact.
We will particularise for RSS.This files are:
AndroidSaxFeedParser.java
package com.customsounds; import java.util.ArrayList; import java.util.List; import android.sax.Element; import android.sax.EndElementListener; import android.sax.EndTextElementListener; import android.sax.RootElement; import android.util.Xml; public class AndroidSaxFeedParser extends BaseFeedParser { static final String RSS = "rss"; public AndroidSaxFeedParser(String feedUrl) { super(feedUrl); } public List<Message> parse() { final Message currentMessage = new Message(); RootElement root = new RootElement(RSS); final List<Message> messages = new ArrayList<Message>(); Element channel = root.getChild(CHANNEL); Element item = channel.getChild(ITEM); item.setEndElementListener(new EndElementListener(){ public void end() { messages.add(currentMessage.copy()); } }); item.getChild(TITLE).setEndTextElementListener(new EndTextElementListener(){ public void end(String body) { currentMessage.setTitle(body); } }); item.getChild(LINK).setEndTextElementListener(new EndTextElementListener(){ public void end(String body) { currentMessage.setLink(body); } }); item.getChild(DESCRIPTION).setEndTextElementListener(new EndTextElementListener(){ public void end(String body) { currentMessage.setDescription(body); } }); item.getChild(PUB_DATE).setEndTextElementListener(new EndTextElementListener(){ public void end(String body) { currentMessage.setDate(body); } }); item.getChild(DATES).setEndTextElementListener(new EndTextElementListener(){ public void end(String body) { currentMessage.setDates(body); } }); try { Xml.parse(this.getInputStream(), Xml.Encoding.UTF_8, root.getContentHandler()); } catch (Exception e) { throw new RuntimeException(e); } return messages; } }
BaseFeedParser.java
package com.customsounds; import java.io.IOException; import java.io.InputStream; import java.net.MalformedURLException; import java.net.URL; public abstract class BaseFeedParser implements FeedParser { // names of the XML tags static final String CHANNEL = "channel"; static final String PUB_DATE = "pubDate"; static final String DESCRIPTION = "description"; static final String LINK = "link"; static final String TITLE = "title"; static final String ITEM = "item"; static final String DATES = "dates"; private final URL feedUrl; protected BaseFeedParser(String feedUrl){ try { this.feedUrl = new URL(feedUrl); } catch (MalformedURLException e) { throw new RuntimeException(e); } } protected InputStream getInputStream() { try { return feedUrl.openConnection().getInputStream(); } catch (IOException e) { throw new RuntimeException(e); } } }
FeedParser.java
package com.customsounds; import java.util.List; public interface FeedParser { List<Message> parse(); }
FeedParserFactory.java
In this class you need to enter your website where the rss or xml is located on your website
package com.customsounds; public abstract class FeedParserFactory { static String feedUrl = "http://mywebsite.com/myrss.rss"; public static FeedParser getParser(){ return getParser(ParserType.ANDROID_SAX); } public static FeedParser getParser(ParserType type){ switch (type){ case SAX: return new SaxFeedParser(feedUrl); case ANDROID_SAX: return new AndroidSaxFeedParser(feedUrl); default: return null; } } }
Message.java
package com.customsounds; import java.net.MalformedURLException; import java.net.URL; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; public class Message implements Comparable<Message>{ static SimpleDateFormat FORMATTER = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss Z"); private String title; private URL link; private String description; private Date date; private String dates; public String getTitle() { return title; } public void setTitle(String title) { this.title = title.trim(); } // getters and setters omitted for brevity public URL getLink() { return link; } public void setLink(String link) { try { this.link = new URL(link); } catch (MalformedURLException e) { throw new RuntimeException(e); } } public String getDescription() { return description; } public void setDescription(String description) { this.description = description.trim(); } public String getDate() { return FORMATTER.format(this.date); } public void setDate(String date) { // pad the date if necessary while (!date.endsWith("00")){ date += "0"; } try { this.date = FORMATTER.parse(date.trim()); } catch (ParseException e) { throw new RuntimeException(e); } } public String getDates() { return dates; } public void setDates(String dates) { this.dates = dates.trim(); } public Message copy(){ Message copy = new Message(); copy.title = title; copy.link = link; copy.description = description; copy.date = date; copy.dates = dates; return copy; } @Override public String toString() { StringBuilder sb = new StringBuilder(); sb.append("Title: "); sb.append(title); sb.append('\n'); sb.append("Date: "); sb.append(this.getDate()); sb.append('\n'); sb.append("Link: "); sb.append(link); sb.append('\n'); sb.append("Description: "); sb.append(description); sb.append('\n'); sb.append("Dates: "); sb.append(dates); return sb.toString(); } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((date == null) ? 0 : date.hashCode()); result = prime * result + ((description == null) ? 0 : description.hashCode()); result = prime * result + ((link == null) ? 0 : link.hashCode()); result = prime * result + ((title == null) ? 0 : title.hashCode()); result = prime * result + ((dates == null) ? 0 : dates.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Message other = (Message) obj; if (date == null) { if (other.date != null) return false; } else if (!date.equals(other.date)) return false; if (description == null) { if (other.description != null) return false; } else if (!description.equals(other.description)) return false; if (link == null) { if (other.link != null) return false; } else if (!link.equals(other.link)) return false; if (title == null) { if (other.title != null) return false; } else if (!title.equals(other.title)) return false; if (dates == null) { if (other.dates != null) return false; } else if (!dates.equals(other.dates)) return false; return true; } public int compareTo(Message another) { if (another == null) return 1; // sort descending, most recent first return another.date.compareTo(date); } }
ParserType
package com.customsounds; /** * */ public enum ParserType{ SAX,ANDROID_SAX; }
RSS Handler
package com.customsounds; import java.util.ArrayList; import java.util.List; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; import static com.customsounds.BaseFeedParser.*; public class RssHandler extends DefaultHandler{ private List<Message> messages; private Message currentMessage; private StringBuilder builder; public List<Message> getMessages(){ return this.messages; } @Override public void characters(char[] ch, int start, int length) throws SAXException { super.characters(ch, start, length); builder.append(ch, start, length); } @Override public void endElement(String uri, String localName, String name) throws SAXException { super.endElement(uri, localName, name); if (this.currentMessage != null){ if (localName.equalsIgnoreCase(TITLE)){ currentMessage.setTitle(builder.toString()); } else if (localName.equalsIgnoreCase(LINK)){ currentMessage.setLink(builder.toString()); } else if (localName.equalsIgnoreCase(DESCRIPTION)){ currentMessage.setDescription(builder.toString()); } else if (localName.equalsIgnoreCase(PUB_DATE)){ currentMessage.setDate(builder.toString()); } else if (localName.equalsIgnoreCase(DATES)){ currentMessage.setDates(builder.toString()); }else if (localName.equalsIgnoreCase(ITEM)){ messages.add(currentMessage); } builder.setLength(0); } } @Override public void startDocument() throws SAXException { super.startDocument(); messages = new ArrayList<Message>(); builder = new StringBuilder(); } @Override public void startElement(String uri, String localName, String name, Attributes attributes) throws SAXException { super.startElement(uri, localName, name, attributes); if (localName.equalsIgnoreCase(ITEM)){ this.currentMessage = new Message(); } } }
SaxFeedParser.java
package com.customsounds; import java.util.List; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; public class SaxFeedParser extends BaseFeedParser { protected SaxFeedParser(String feedUrl){ super(feedUrl); } public List<Message> parse() { SAXParserFactory factory = SAXParserFactory.newInstance(); try { SAXParser parser = factory.newSAXParser(); RssHandler handler = new RssHandler(); parser.parse(this.getInputStream(), handler); return handler.getMessages(); } catch (Exception e) { throw new RuntimeException(e); } } }
XmlPullFeedParser.java
package com.customsounds; import java.util.ArrayList; import java.util.List; import org.xmlpull.v1.XmlPullParser; import android.util.Log; import android.util.Xml; public class XmlPullFeedParser extends BaseFeedParser { public XmlPullFeedParser(String feedUrl) { super(feedUrl); } public List<Message> parse() { List<Message> messages = null; XmlPullParser parser = Xml.newPullParser(); try { // auto-detect the encoding from the stream parser.setInput(this.getInputStream(), null); int eventType = parser.getEventType(); Message currentMessage = null; boolean done = false; while (eventType != XmlPullParser.END_DOCUMENT && !done){ String name = null; switch (eventType){ case XmlPullParser.START_DOCUMENT: messages = new ArrayList<Message>(); break; case XmlPullParser.START_TAG: name = parser.getName(); if (name.equalsIgnoreCase(ITEM)){ currentMessage = new Message(); } else if (currentMessage != null){ if (name.equalsIgnoreCase(LINK)){ currentMessage.setLink(parser.nextText()); } else if (name.equalsIgnoreCase(DESCRIPTION)){ currentMessage.setDescription(parser.nextText()); } else if (name.equalsIgnoreCase(PUB_DATE)){ currentMessage.setDate(parser.nextText()); } else if (name.equalsIgnoreCase(TITLE)){ currentMessage.setTitle(parser.nextText()); } else if (name.equalsIgnoreCase(DATES)){ currentMessage.setDates(parser.nextText()); } } break; case XmlPullParser.END_TAG: name = parser.getName(); if (name.equalsIgnoreCase(ITEM) && currentMessage != null){ messages.add(currentMessage); } else if (name.equalsIgnoreCase(CHANNEL)){ done = true; } break; } eventType = parser.next(); } } catch (Exception e) { Log.e("AndroidNews::PullFeedParser", e.getMessage(), e); throw new RuntimeException(e); } return messages; } }
For this parser to work you must follow this structure on the building of your .rss file:
So now we will make a ListView in Android where we will parse the informations from this rss…
Main.java
public class ListExample extends ListActivity { public final static String ITEM_TITLE = "title"; public final static String ITEM_CAPTION = "caption"; public final static String ITEM_VALUE1="value1"; public final static String ITEM_VALUE2="value2"; public Map<String,?> createItem(String title, String caption,String value1,String value2) { Map<String,String> item = new HashMap<String,String>(); item.put(ITEM_TITLE, title); item.put(ITEM_CAPTION, caption); item.put(ITEM_VALUE1, value1); item.put(ITEM_VALUE2, value2); return item; } private List<Message> messages; Message msg1; @Override public void onCreate(Bundle icicle) { super.onCreate(icicle); setContentView(R.layout.listexample); loadFeed(ParserType.ANDROID_SAX);} private void loadFeed(ParserType type){ try{ FeedParser parser = FeedParserFactory.getParser(type); messages = parser.parse(); List<Map<String,?>> security = new LinkedList<Map<String,?>>(); for (Message msg : messages){ security.add(createItem(msg.getTitle()," "," ",msg.getDescription())); } SimpleAdapter adapter= new SimpleAdapter(this, security, R.layout.list_complex, new String[] { ITEM_TITLE, ITEM_CAPTION,ITEM_VALUE1,ITEM_VALUE2 }, new int[] { R.id.TextView02, R.id.TextView01 ,R.id.TextView04,R.id.Button02 }); this.setListAdapter(adapter); } catch (Throwable t){ } } } }