Я использую парсер SAX, который поставляется с JDK7. Я пытаюсь получить объявление DOCTYPE, но ни один из методов в DefaultHandler
похоже, не был уволен за него. Что мне не хватает?
import java.io.StringReader;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
public class Problem {
public static void main(String[] args) throws Exception {
String xml = "<!DOCTYPE HTML><html><head></head><body></body></html>";
SAXParser saxParser = SAXParserFactory.newInstance().newSAXParser();
InputSource in = new InputSource(new StringReader(xml));
saxParser.parse(in, new DefaultHandler() {
@Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
System.out.println("Element: " + qName);
}
});;
}
}
Это дает:
Element: html
Element: head
Element: body
Я хочу, чтобы он производил:
DocType: HTML
Element: html
Element: head
Element: body
Как получить DocType?
Обновление: похоже, существует класс DefaultHandler2
для расширения. Могу ли я использовать это как замену?
Вместо DefaultHander используйте org.xml.sax.ext.DefaultHandler2, у которого есть метод startDTD().
Сообщите о начале объявлений DTD, если они есть. Этот метод предназначен для отчета о начале декларации DOCTYPE; если у документа нет объявления DOCTYPE, этот метод не будет вызываться.
Все объявления, сообщаемые через события DTDHandler или DeclHandler, должны отображаться между событиями startDTD и endDTD. Предполагается, что декларации принадлежат внутреннему подмножеству DTD, если они не появляются между событиями startEntity и endEntity. Комментарии и инструкции по обработке DTD также должны сообщаться между событиями startDTD и endDTD в их первоначальном порядке (логическом) вхождении; однако они не должны появляться в правильных местах относительно событий DTDHandler или DeclHandler.
Обратите внимание, что события start/endDTD будут отображаться в событиях start/endDocument из ContentHandler и перед первым событием startElement.
Однако вы также должны установить LexicalHandler для XML Reader.
import java.io.StringReader;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.ext.DefaultHandler2;
public class Problem{
public static void main(String[] args) throws Exception {
String xml = "<!DOCTYPE html><hml><img/></hml>";
SAXParser saxParser = SAXParserFactory.newInstance().newSAXParser();
InputSource in = new InputSource(new StringReader(xml));
DefaultHandler2 myHandler = new DefaultHandler2(){
@Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
System.out.println("Element: " + qName);
}
@Override
public void startDTD(String name, String publicId,
String systemId) throws SAXException {
System.out.println("DocType: " + name);
}
};
saxParser.setProperty("http://xml.org/sax/properties/lexical-handler",
myHandler);
saxParser.parse(in, myHandler);
}
}