用工厂方法产生一个SAXPareser实例:
SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser pareser = factory.newSAXParser();
我们需要写一个事件处理类来驱动parser的Callback方法,只需要实现部分方法所以我们继承DefaultHandler类即可,DefaultHandler提供了ContentHandler的默认实现。我们需要实现一下方法:
void characters(char[] ch, int start, int length)
void endElement(String uri, String localName, String name)
void startDocument()
startElement(String uri, String localName, String name, Attributes attributes)
然后打开一个RSS的URL获得输入流
InputStream inputStream = new URL(“http://…”).openConnection().getInputStream();
分析feed
pareser.parse(inputStream,handler);
详细的实现代码:
//定义一个接口,方便扩展,可以用其他的XML分析API
import java.util.List; public interface FeedParser { List<Message> parse(); }
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"; 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); } } }
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); } } }
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 org.developerworks.android.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()); System.out.println(builder.toString()); } else if (localName.equalsIgnoreCase(LINK)){ currentMessage.setLink(builder.toString()); System.out.println(builder.toString()); } else if (localName.equalsIgnoreCase(DESCRIPTION)){ currentMessage.setDescription(builder.toString()); System.out.println(builder.toString()); } else if (localName.equalsIgnoreCase(PUB_DATE)){ currentMessage.setDate(builder.toString()); System.out.println(builder.toString()); } else if (localName.equalsIgnoreCase(ITEM)){ messages.add(currentMessage); System.out.println(builder.toString()); } 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(); } } }
public abstract class FeedParserFactory { static String feedUrl = "http://www.androidster.com/android_news.rss"; public static FeedParser getParser(){ return getParser(ParserType.SAX); } public static FeedParser getParser(ParserType type){ switch (type){ case SAX: return new SaxFeedParser(feedUrl); case DOM: return new DomFeedParser(feedUrl); case ANDROID_SAX: return new AndroidSaxFeedParser(feedUrl); case XML_PULL: return new XmlPullFeedParser(feedUrl); default: return null; } } }