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中完成此操作,但是希望这可以帮助遇到此问题的下一个人。

10-07 22:06