我想解析以下XML文档来解析其中的所有实体:

 <!DOCTYPE doc SYSTEM 'mydoc.dtd'>
 <doc>&title;</doc>

我的EntityResolver应该从数据库中获取具有给定系统ID的外部实体,然后执行解析,请参见下面的插图:
 private static class MyEntityResolver
 {
    public InputSource resolveEntity(String publicId, String systemId)
        throws SAXException, IOException
    {
        // At this point, systemId is always absolutized to the current working directory,
        // even though the XML document specified it as relative.
        // E.g. "file:///H:/mydoc.dtd" instead of just "mydoc.dtd"
        // Why???  How can I prevent this???

        SgmlEntity entity = findEntityFromDatabase(systemId);
        InputSource is = new InputSource(new ByteArrayInputStream(entity.getContents()));
        is.setPublicId(publicId);
        is.setSystemId(systemId);
        return is;
    }
 }

我尝试同时使用DOM(DocumentBuilder)和SAX(XMLReader),将实体解析器设置为MyEntityResolver(即setEntityResolver(new MyEntityResolver())),但是systemId中的MyEntityResolver#resolveEntity(String publicId, String systemId)始终被绝对化为当前工作目录。

我也尝试调用setFeature("http://xml.org/sax/features/resolve-dtd-uris", false);,但这没有任何帮助。

那我怎样才能达到我想要的呢?

谢谢!

最佳答案

显然,还有一个名为EntityResolver2的接口(interface),它是旧EntityResolver的扩展。 (谈论令人困惑的名称!)

无论如何,我发现EntityResolver2实现了我想要的功能,也就是说,它没有对systemId进行任何更改,因此它始终是XML文档中指定的内容。

10-04 19:12