8

我想解析以下 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 (ie ) ,setEntityResolver(new MyEntityResolver())但总是被绝对化为当前工作目录。 systemIdMyEntityResolver#resolveEntity(String publicId, String systemId)

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

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

谢谢!

4

2 回答 2

8

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

无论如何,我发现EntityResolver2实现了我想要的,也就是说,它没有对systemId.

于 2009-11-03T01:25:13.710 回答
0

EntityResolver Javadocs

如果系统标识符是 URL,则 SAX 解析器必须在将其报告给应用程序之前对其进行完全解析。

此外,org.xml.sax 文档对 resolve-dtd-uris 功能有这样的说法:

它不适用于 EntityResolver.resolveEntity(),它不用于报告声明...

我认为您要么必须将基本 URI 设置为可以使用的东西,要么使用公共 ID 而不是系统 ID。

于 2009-10-30T06:42:31.277 回答