Как мы можем проанализировать информацию DOCTYPE, используя XMLEventReader? - PullRequest
4 голосов
/ 18 августа 2011

У меня есть некоторый существующий код, который анализирует пространство имен элемента верхнего уровня, чтобы определить, какой тип 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 Ответ

3 голосов
/ 12 декабря 2016

Я знаю, что это старый пост, но я не смог найти ответ в Интернете, пока не нашел ваш вопрос, который направил меня в правильном направлении.

Здесь внешние неразобранные сущности для 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();
}
...