我有一些现有的代码解析顶级元素名称空间,以确定我们正在查看哪种XML文件。
XMLEventReader reader = createXMLEventReader(...);
try {
while (reader.hasNext()) {
XMLEvent event = reader.nextEvent();
switch (event.getEventType()) {
case XMLStreamConstants.DTD:
// No particularly useful information here?
//((DTD) event).getDocumentTypeDeclaraion();
break;
case XMLStreamConstants.START_ELEMENT:
formatInfo.qName = ((StartElement) event).getName();
return formatInfo;
default:
break;
}
}
} finally {
reader.close();
}
如果我允许解析器从Web加载DTD,getDocumentTypeDeclaraion()
包含一个巨大的字符串,其中包含的信息比我知道如何处理更多,因为它会在处理之前将所有相关的DTD插入到字符串中。另一方面,如果我阻止解析器从Web加载DTD(最好是因为显而易见的原因),它只给我字符串"<!DOCTYPE"
。
是否无法取回DOCTYPE中的值?
我正在使用JRE随附的默认解析器,以防万一。
答案 0 :(得分:3)
我知道这是一篇很老的帖子但我找不到网上的答案,直到我发现你的问题指向了正确的方向。
这里通过切换XMLEvent#getEventType()
方法给出的值来检索DTD的外部未解析实体。
XMLInputFactory factory = XMLInputFactory.newInstance();
factory.setXMLResolver(new XMLResolver() {
@Override
public Object resolveEntity(String publicID, String systemID,
String baseURI, String namespace) throws XMLStreamException {
//return a closed input stream if external entities are not needed
return new InputStream() {
@Override
public int read() throws IOException {
return -1;
}
};
}
});
XMLEventReader reader = factory.createXMLEventReader( . . . );
try {
while(reader.hasNext()) {
XMLEvent event = reader.nextEvent();
switch (event.getEventType()) {
case XMLStreamConstants.DTD:
List<EntityDeclaration> entities = ((DTD)event).getEntities();
if (entities != null) {
for (EntityDeclaration entity : entities)
System.out.println(entity.getName() + " = " + entity.getSystemId());
}
break;
case . . .
}
}
} finally {
reader.close();
}