我尝试使用DOCTYPE中指定的私有外部DTD解析XML文件,如下所示:
<!DOCTYPE MY1 SYSTEM "my1.dtd">
要在本地处理此DTD以进行验证,我为EntityResolver
指定了XMLReader parser
:
//use local DTD
parser.setEntityResolver(new EntityResolver() {
@Override
public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException {
if (systemId.contains(my1Dtd)) {
return new InputSource(MyClass.class.getResourceAsStream(MY1_DTD_RESOURCE_PATH));
} else {
return null;
}
}
});
此InputSource
正确返回,但是存在与DTD相关的问题:在DTD内部有对另一个DTD的引用。所以我将所有DTD放在同一个包中。但是当我在Tomcat FileNotFoundException D:\apache-tomcat-6.0.29\bin\my2.dtd (The system cannot find the file specified)
上部署的应用程序被抛出时。
我的问题是:我们如何正确指定此依赖关系?是应该用resolveEntity
方法构建还是我在路径中犯了一个错误(my2.dtd
在<!ENTITY % MY2 SYSTEM "my2.dtd">
内声明为my1.dtd
并存储在同一个包中。
答案 0 :(得分:0)
当解析器需要加载my2.dtd文件时,也应该调用resolveEntity
。
因此,你需要以类似的方式修改它:
public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException {
if (systemId.contains(my1Dtd)) {
return new InputSource(MyClass.class.getResourceAsStream(MY1_DTD_RESOURCE_PATH));
} else if (systemId.contains(my2Dtd)) {
return new InputSource(MyClass.class.getResourceAsStream(MY2_DTD_RESOURCE_PATH));
} else {
return null;
}
}
但是,为避免此类工作,您应该考虑使用解析器,例如the Apache resolver。此解析器依赖于OASIS entity resolution / XML catalogs,它允许您创建XML格式的目录,由解析程序读取,这样您每次有新DTD或将其移动到其他位置时都不需要修改代码管他呢。 (此解析程序包与Apache Xerces发行版捆绑在一起,如果它已经是您正在使用的解析器)。