Xerces声称允许将XML Catalog支持添加到这样的阅读器中:
XMLCatalogResolver resolver = new XMLCatalogResolver();
resolver.setPreferPublic(true);
resolver.setCatalogList(catalogs);
XMLReader reader = XMLReaderFactory.createXMLReader(
"org.apache.xerces.parsers.SAXParser");
reader.setProperty("http://apache.org/xml/properties/internal/entity-resolver",
resolver);
但是,一旦执行此操作,架构中的任何
<xs:include/>
标记都将不再被处理。好像XMLCatalogResolver
一旦添加,就成为唯一的实体解析位置,因此include不再起作用。 Eclipse OTOH使用相同的目录成功进行了验证,因此应该为possilbe。有没有解决的办法,或者是否有其他基于Java的支持目录的验证器?
谢谢,多米尼克。
最佳答案
我终于通过覆盖XMLCatalogResolver
并记录了对resolveEntity()
方法的各种调用来解决了这个问题。我观察到有3种类型的调用,其中只有一种类型可以使用XML目录来解决。因此,我只针对其他两种调用类型直接返回了FileInputStream
。
这是我在自定义XMLCatalogResolver
类中使用的代码:
public XMLInputSource resolveEntity(XMLResourceIdentifier resourceIdentifier)
throws IOException
{
if(resourceIdentifier.getExpandedSystemId() != null)
{
return new XMLInputSource(resourceIdentifier.getPublicId(),
resourceIdentifier.getLiteralSystemId(),
resourceIdentifier.getBaseSystemId(),
new FileReader(getFile(resourceIdentifier.getExpandedSystemId())),
"UTF-8");
}
else if((resourceIdentifier.getBaseSystemId() != null) &&
(resourceIdentifier.getNamespace() == null))
{
return new XMLInputSource(resourceIdentifier.getPublicId(),
resourceIdentifier.getLiteralSystemId(),
resourceIdentifier.getBaseSystemId(),
new FileReader(getFile(resourceIdentifier.getBaseSystemId())),
"UTF-8");
}
else
{
return super.resolveEntity(resourceIdentifier);
}
}
private File getFile(String urlString) throws MalformedURLException
{
URL url = new URL(urlString);
return new File(url.toURI());
}
我不确定为什么默认情况下不会在Xerces中完成此操作,但是希望这可以帮助遇到此问题的下一个人。