Как мы можем проанализировать информацию 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();
}
Другие вопросы по тегам