我正在使用Apache Web服务xml rpc库向rpc服务发出请求。该过程中的某个位置是一个xml文档,其中包含对http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd的DTD引用,库在解析XML时会尝试下载。该下载因503状态代码而失败,因为w3c阻止从Java客户端重复下载此静态文档。
解决方案是XML Catalogs,用于本地缓存DTD。但是,虽然我可以找到直接在JAXP SAXParser实例上设置EntityHandler以启用目录解析器支持的示例,但实际上我并没有访问底层解析器。它只是被xml rpc库使用。有什么方法可以设置全局属性或者告诉JAXP使用XML目录的东西吗?
答案 0 :(得分:1)
我认为您需要系统属性xml.catalog.files
。
查看http://xml.apache.org/commons/components/resolver/resolver-article.html
顺便说一句,这是谷歌搜索jaxp catalog
的第三次打击
答案 1 :(得分:1)
不幸的是,设置xml.catalog.files对解析器工厂没有任何影响。理想情况下,它当然应该是,但是使用解析器的唯一方法是以某种方式添加一个方法,将解析委托给SAX解析器使用的处理程序中的目录解析程序。
如果您已经在使用SAX解析器,那很简单:
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);
否则,您需要弄清楚是否可以提供自己的实体解析器。使用javax.xml.parsers.DocumentBuilder,您可以。使用scala.xml.XML对象,您可以使用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