我需要解析一堆传入的 XML 文档,但它不包含 DOCTYPE(它们都有不同的 DTD)。 DTD是我自己创建的。如何根据本地存储为文件的 DTD 验证 XML 文件?我有以下要求:
- 所有 DTD(针对不同的 XML)将被加载到内存中一次,传入 XML 时不会查看本地存储区域。
- 根据加载的 DTD 文件验证传入的 XML。
谢谢
最佳答案
您需要在 SAX 解析器上使用本地实体解析器,以下是如何实现它的示例:
class LocalEntityResolver implements EntityResolver {
private static final Logger LOG = ESAPI.getLogger(LocalEntityResolver.class);
private static final Map<String, String> DTDS;
static {
DTDS = new HashMap<String, String>();
DTDS.put("-//W3C//DTD XHTML 1.0 Transitional//EN",
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd");
DTDS.put("-//W3C//ENTITIES Latin 1 for XHTML//EN",
"http://www.w3.org/TR/xhtml1/DTD/xhtml-lat1.ent");
DTDS.put("-//W3C//ENTITIES Symbols for XHTML//EN",
"http://www.w3.org/TR/xhtml1/DTD/xhtml-symbol.ent");
DTDS.put("-//W3C//ENTITIES Special for XHTML//EN",
"http://www.w3.org/TR/xhtml1/DTD/xhtml-special.ent");
}
@Override
public InputSource resolveEntity(String publicId, String systemId)
throws SAXException, IOException {
InputSource input_source = null;
if (publicId != null && DTDS.containsKey(publicId)) {
LOG.debug(Logger.EVENT_SUCCESS, "Looking for local copy of [" + publicId + "]");
final String dtd_system_id = DTDS.get(publicId);
final String file_name = dtd_system_id.substring(
dtd_system_id.lastIndexOf('/') + 1, dtd_system_id.length());
InputStream input_stream = FileUtil.readStreamFromClasspath(
file_name, "your/dtd/location",
getClass().getClassLoader());
if (input_stream != null) {
LOG.debug(Logger.EVENT_SUCCESS, "Found local file [" + file_name + "]!");
input_source = new InputSource(input_stream);
}
}
return input_source;
}
}
关于java - 如何使用java验证XML?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5140648/