Xerces可以同时支持XMLCatalogResolver和<xs:include>吗?</xs:include>

时间:2012-04-02 00:58:44

标签: java xml schema xmlcatalog

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的验证器支持目录?

谢谢,多米尼克。

1 个答案:

答案 0 :(得分: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中完成,但希望这有助于下一个遇到此问题的人。