This post originated from an RSS feed registered with Java Buzz
by Wilfred Springer.
Original Post: DTD Resolution Be Gone!
Feed Title: Distributed Reflections of the Third Kind
Feed URL: http://blog.flotsam.nl/feeds/posts/default
Feed Description: Distributed Reflections of the Third Kind
I just read Cay Horstmanns post on The Sordid Tale of XML Catalogs. I could agree more: it's a mess. Not to so long ago, I had to write some software for pulling down XML content from a web site. I used Nathan Hamblan's Dispatch library and Scala's built-in support for traversing an XML document the easy way. And immediately noticed that parsing the document did take way more time than it should. It turns out that upon parsing the document, the parser pulled down a whole slew of DTDs and entity definitions. My first response was to find a way to bake a Catalog based resolver in somewhere. But then - I'm not particularly font of the current implementations. (Are they even maintained.) And since this was pure production, I had to make it working as quickly as possible. So this is what I did to get out of the mess:First of all, I defined a trait:
trait NoDtdResolution extends XMLLoader[Node] {
override def parser = { val f = SAXParserFactory.newInstance() f.setNamespaceAware(false) f.setValidating(false) val result = f.newSAXParser() val reader = result.getXMLReader reader.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false) result }
}
Normally, in Scala, you would load an XML document like this:
XML.load(...)
However, if you do it like that, you will get a parser that downloads the DTDs as well. And I don't want that. With the trait I created, I could load an XML document like this:
val loader = new NoBindingFactoryAdapter with NoDtdResolution loader.load(...)
... without the DTDs being resolved. (I guess you could do something similar to install a catalog.) Which it great, but unfortunately, it doesn't make Dispatch aware of it. So, in dispatch, if you use the <> operator, it will still download the XML file and parse with DTD loading activated. So I needed another operator: one that uses a NoBindingFactoryAdapterwithout DTD resolution:
trait ImplicitXmlHandlers extends ImplicitHandlerVerbs { implicit def handlerToXmlHandlers(r: HandlerVerbs) = new XmlHandlers(r) implicit def requestToXmlHandlers(r: Request) = new XmlHandlers(r) }
object XmlHandlers extends ImplicitXmlHandlers
class XmlHandlers(subject: HandlerVerbs) {
private val tolerantAdapter = new NoBindingFactoryAdapter with NoDtdResolution