Java:如何防止EntityResolver中的’systemId’#resolveEntity(String publicId,String systemId)从绝对化到当前工作目录

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

 &title; 

我的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. // Eg "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()) ),但MyEntityResolver#resolveEntity(String publicId, String systemId) systemId MyEntityResolver#resolveEntity(String publicId, String systemId)始终被绝对化为当前的工作目录。

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

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

谢谢!

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

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

从EntityResolver Javadocs :

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

此外, org.xml.sax文档还有关于resolve-dtd-urisfunction的说法:

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

我想你要么将你的base-URI设置为你可以使用的东西,要么使用public-ID而不是system-IDs。

    Interesting Posts