的Java:如何防止“的systenId”中的EntityResolver#resolveEntity(字符串publicId,字符串的systenId)被绝对化到当前工作目录
我想解析以下XML文件来解决它的所有实体:的Java:如何防止“的systenId”中的EntityResolver#resolveEntity(字符串publicId,字符串的systenId)被绝对化到当前工作目录
<!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的) ,将实体解析器设置为MyEnt ityResolver(即setEntityResolver(new MyEntityResolver())
),但systemId
在MyEntityResolver#resolveEntity(String publicId, String systemId)
总是被absolutized到当前工作目录。
我也试过打电话setFeature("http://xml.org/sax/features/resolve-dtd-uris", false);
,但那并没有什么帮助。
那么我该如何实现我想要的?
谢谢!
显然,还有另外一个接口叫做EntityResolver2,它是旧的EntityResolver的扩展。 (谈论混淆的名字!)
无论如何,我发现EntityResolver2
达到我想要的东西,也就是说,它不会做任何更改systemId
,所以它永远究竟是什么在XML文档中指定。
如果系统标识符是一个URL,该 SAX解析器必须将其报告给 应用程序之前完全 解决它。
此外,org.xml.sax docs有这样说的决心,DTD的URI的功能:
它并不适用于 EntityResolver.resolveEntity(),它 不用于报告的声明。 ..
我认为你必须设置你的base-URI为你可以使用的东西,或者使用public-id而不是system-id。