Как мы можем проанализировать информацию DOCTYPE, используя XMLEventReader?
У меня есть некоторый существующий код, который анализирует пространство имен элемента верхнего уровня, чтобы определить, какой тип 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();
}
Если я позволю парсеру загружать DTD из Интернета, getDocumentTypeDeclaraion()
содержит гигантскую строку с гораздо большим количеством информации, чем я знаю, как иметь дело, поскольку она вставляет все связанные DTD в строку перед передачей. С другой стороны, если я блокирую DTD загрузки парсера из Интернета (что в любом случае предпочтительно по понятным причинам), он выдаст только строку, "<!DOCTYPE"
,
Нет ли способа вернуть значения внутри DOCTYPE?
Я использую парсер по умолчанию, который поставляется вместе с JRE, на случай, если это имеет значение.
1 ответ
Я знаю, что это старый пост, но я не мог найти ответ в Интернете, пока не нашел ваш вопрос, который указал мне правильное направление.
Здесь внешние неразобранные объекты для DTD извлекаются путем включения значения, заданного XMLEvent#getEventType()
метод.
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();
}