Using an XML directory with a Java library that uses JAXP internally

I am using the xml rpc library for the Apache web service to query the rpc service. Somewhere in this process there is an xml document with a DTD link at http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd , which the library tries to load when parsing XML. This download failed with a status code of 503, because w3c blocks the reloading of this largely static document from Java clients.

The solution is XML directories for local DTD caching. However, although I can find examples of installing EntityHandler in a JAXP SAXParser instance directly to enable directory parser support, in fact I do not have access to the main parser. It is just used by the xml rpc library. Is there a way to set a global property or something that JAXP will say about using XML directories?

+7
java xml
source share
2 answers

I think you need the xml.catalog.files system property.

Take a look at http://xml.apache.org/commons/components/resolver/resolver-article.html

By the way, this was the third hit in the Google search jaxp catalog

+1
source share

Unfortunately, setting xml.catalog.files does not affect the factory parser. Ideally, this should, of course, but the only way to use the resolver is to somehow add a method that delegates permission to the directory resolver in the handler that uses the SAX analyzer.

If you already use the SAX parser, this is pretty easy:

  final CatalogResolver catalogResolver = new CatalogResolver(); DefaultHandler handler = new DefaultHandler() { public InputSource resolveEntity (String publicId, String systemId) { return catalogResolver.resolveEntity(publicId, systemId); } public void startElement(String namespaceURI, String lname, String qname, Attributes attrs) { // the stuff you'd normally do } ... }; SAXParserFactory factory = SAXParserFactory.newInstance(); factory.setNamespaceAware(true); SAXParser saxParser = factory.newSAXParser(); String url = args.length == 0 ? "http://horstmann.com/index.html" : args[0]; saxParser.parse(new URL(url).openStream(), handler); 

Otherwise, you need to find out if you can provide your own entity recognizer. Using javax.xml.parsers.DocumentBuilder you can. With the scala.xml.XML object you cannot, but you can use subterfuge:

 val res = new com.sun.org.apache.xml.internal.resolver.tools.CatalogResolver val loader = new factory.XMLLoader[Elem] { override def adapter = new parsing.NoBindingFactoryAdapter() { override def resolveEntity(publicId: String, systemId: String) = { res.resolveEntity(publicId, systemId) } } } val doc = loader.load(new URL("http://horstmann.com/index.html"))enter code here 
+1
source share

All Articles