在 SAX 解析器中处理具有依赖性的私有外部 DTD
Handle private external DTD with dependencies in SAX parser
我正在尝试使用 DOCTYPE 中指定的专用外部 DTD 解析 XML 文件,如下所示:
<!DOCTYPE MY1 SYSTEM "my1.dtd">
为了在本地处理此 DTD 以进行验证,我为 XMLReader parser
指定了 EntityResolver
:
//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
在my1.dtd
里面声明为<!ENTITY % MY2 SYSTEM "my2.dtd">
,存放在同一个包里)
当解析器需要加载 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. This resolver relies on the OASIS entity resolution / XML catalogs,它允许您创建 XML 格式的目录,由解析器读取,这样您就不会每次你有一个新的 DTD 或将它移动到另一个地方或其他任何地方时都需要修改你的代码。
(这个解析器包与 Apache Xerces 发行版捆绑在一起,如果它已经是您正在使用的解析器的话)。
我正在尝试使用 DOCTYPE 中指定的专用外部 DTD 解析 XML 文件,如下所示:
<!DOCTYPE MY1 SYSTEM "my1.dtd">
为了在本地处理此 DTD 以进行验证,我为 XMLReader parser
指定了 EntityResolver
:
//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
在my1.dtd
里面声明为<!ENTITY % MY2 SYSTEM "my2.dtd">
,存放在同一个包里)
当解析器需要加载 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. This resolver relies on the OASIS entity resolution / XML catalogs,它允许您创建 XML 格式的目录,由解析器读取,这样您就不会每次你有一个新的 DTD 或将它移动到另一个地方或其他任何地方时都需要修改你的代码。 (这个解析器包与 Apache Xerces 发行版捆绑在一起,如果它已经是您正在使用的解析器的话)。