1

Xerces 声称允许向阅读器添加 XML 目录支持,如下所示:

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一旦添加,它就成为实体解析的唯一去处,因此包含不再起作用。Eclipse OTOH 使用相同的目录成功验证,所以它应该是可能的。

有没有办法解决这个问题,或者是否有任何其他支持目录的基于 Java 的验证器?

谢谢,多米尼克。

4

1 回答 1

1

我终于通过覆盖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 中默认情况下不会这样做,但希望这对遇到此问题的下一个人有所帮助。

于 2012-04-06T05:01:31.890 回答