As mentioned earlier the RSSHandler extends the XML parser's predefined
HandlerBase and overrides the startElement, endElement, and
charData methods in order to be informed when individual RSS tags are recognized
and what their enclosed character data is.
package com.exploringxml.rss;
import java.net.URL;
import com.microstar.xml.*;
public class RSSHandler extends HandlerBase {
RSSChannel channel;
boolean readingChannel;
boolean readingImage;
boolean readingItem;
boolean readingTitle;
boolean readingLink;
boolean readingDescription;
boolean readingURL;
boolean addedTitle;
boolean addedLink;
int itemCounter;
public RSSHandler(RSSChannel c) {
channel = c;
}
public void startElement(String s) throws Exception {
if (s.equals(RSSChannel.ChannelTag)) readingChannel = true;
else if (s.equals(RSSChannel.ImageTag)) readingImage = true;
else if (s.equals(RSSChannel.ItemTag)) readingItem = true;
else if (s.equals(RSSChannel.TitleTag)) readingTitle = true;
else if (s.equals(RSSChannel.LinkTag)) readingLink = true;
else if (s.equals(RSSChannel.DescriptionTag)) readingDescription = true;
else if (s.equals(RSSChannel.URLTag)) readingURL = true;
}
public void endElement(String s) throws Exception {
if (s.equals(RSSChannel.ChannelTag)) readingChannel = false;
else if (s.equals(RSSChannel.ImageTag)) readingImage = false;
else if (s.equals(RSSChannel.ItemTag)) readingItem = false;
else if (s.equals(RSSChannel.TitleTag)) readingTitle = false;
else if (s.equals(RSSChannel.LinkTag)) readingLink = false;
else if (s.equals(RSSChannel.DescriptionTag)) readingDescription = false;
else if (s.equals(RSSChannel.URLTag)) readingURL = false;
}
The boolean variables keep track of the elements in which the parsing takes place.
This enables us to put the incoming character data (see below) in the
right property of the RSSChannel. Please note that these functions will be
called by the XML parser as it reads the RSS source file, so don't spend your time
trying to locate the caller of these methods in my code.
public void charData(char[] chars, int from, int to) throws Exception {
if (readingChannel && readingTitle) channel.setChannelTitle(new String(chars, from, to));
else if (readingChannel && readingLink) channel.setChannelLink(new URL(new String(chars, from, to)));
else if (readingChannel && readingDescription) channel.setChannelDescription(new String(chars, from, to));
else if (readingImage && readingTitle) channel.setImageTitle(new String(chars, from, to));
else if (readingImage && readingLink) channel.setImageLink(new URL(new String(chars, from, to)));
else if (readingImage && readingURL) channel.setImageURL(new URL(new String(chars, from, to)));
else if (readingItem && readingTitle) {
if (addedTitle) itemCounter++; // skip missing link
channel.setItemTitle(new String(chars, from, to), itemCounter);
addedTitle = true;
}
else if (readingItem && readingLink) {
if (addedLink) itemCounter++; // skip missing title
channel.setItemLink(new URL(new String(chars, from, to)), itemCounter);
addedLink = true;
}
if (addedTitle && addedLink) { itemCounter++; addedTitle=addedLink=false; }
}
}
Here we fill the data into the right slots of the channel, based on the values of the
boolean variables. The itemCounter implements
some basic logic to ensure we set the right item link and title together, and skip
missing entries.
This code expects a valid piece of RSS and does not try to validate the contents, so
the results with some arbitrary XML that does not represent valid RSS might be surprising.
It also does not use the full set of RSS attributes such as update intervals.
Now we look at the bit that starts the parsing and receives the attributes
via the handler, the RSSChannel.