用工厂方法产生一个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;
}
}
}