Paul Hammant's Blog: Using XStream to process standardized XML documents
Background (being delisted from Javablogs)
PaulHammant.com was thrown off Javablogs.com for having one too many non-Java postings. Mike Cannon-Brookes forced me to sink an 'Irish car bomb' (with about 20 others) on Tuesday in matter of seconds and provide a second RSS feed to get listed again. I earn about 50c a month from Google ads. It's a pretty important supplement to a paultry ThoughtWorks wage...Given I stupidly hand edit this blog, I thought I'd try a little automation. That would mean something that could create a second RSS feed that would only contain Java related blog entries. The most recent work to XStream allows XML attributes to be used as well as elements for encoding. RSS does not leverage a lot of attributes (it's quite element normal), but there is one key one - <rss version="x.y"> - that needs the latest changes to XStream to function.
POJOs for RSS
Here are is the core Java POJO classes that cover the major elements of RSS 0.91public class Rss {The version attribute on the root <rss> element needs a special class...
Version version;
Channel channel;
}
public class Channel {
String title, link, description, language, webMaster, pubDate;
List items = new ArrayList();
}
public class Item {
String title, link, description;
}
public class Version {
private String value;
public Version(String value) {
this.value = value;
}
public String getValue() {... and a special converter to link it up:
return value;
}
}
import com.thoughtworks.xstream.converters.basic.AbstractSingleValueConverter;And here's the final helper class to do the conversion from/to RSS document to an object model:
public class VersionConverter extends AbstractSingleValueConverter {
public boolean canConvert(Class type) {
return type.equals(Version.class);
}
public String toString(Object obj) {
return obj == null ? null : ((Version) obj).getValue();
}
public Object fromString(String str) {
return new Version(str);
}
}
public class RssConverter {And using it...
private XStream xs;
public RssConverter(XStream xs) {
this.xs = xs;
xs.alias("rss", Rss.class);
xs.alias("item", Item.class);
xs.addImplicitCollection(Channel.class, "items");
xs.useAttributeFor("version", Version.class);
xs.registerConverter(new VersionConverter());
}
public RssConverter() {
this(new XStream(new DomDriver()));
}
public Rss fromXml(FileInputStream fileInputStream) {
return (Rss) xs.fromXML(fileInputStream);
}
public void toXml(Rss rss, OutputStream stream) {
xs.toXML(rss, stream);
}
}
FileInputStream fis = new FileInputStream("../blog/index.xml");I'll speak to Joe, Mauro and Jörg about a comprehensive RSS class model in the XStream project. If anyone is interested in contributing (unit tested) code then send me an email.
RssConverter converter = new RssConverter();
Rss rss = converter.fromXml(fis);
...
converter.toXML(rss, new FileOutputStream("../blog/java-index.xml"));
Other XML forms
Actually, I'd love to see as many 'standard' XML forms tackled as possible. XStream is should be able to cope with most of the simple XML based standards.For example. RSS's competitor Atom looks like quite an easy job for XStream. See http://en.wikipedia.org/wiki/Atom_(standard)
Others like ebXml, XSL, XUL etc do not look so encodable. See http://www.perfectxml.com/XMLAcronyms.asp
Published
May 21st, 2006