4

我有一些现有的代码可以解析顶级元素名称空间以确定我们正在查看的 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 附带的默认解析器,以防万一。

4

1 回答 1

3

我知道这是一篇旧帖子,但我无法在网上找到答案,直到我找到你的问题,它为我指明了正确的方向。

在这里,通过打开方法给定的值来检索 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();
}
于 2016-12-12T16:09:51.157 回答