Получение деталей DOCTYPE с использованием SAX (JDK 7)

1

Я использую парсер 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 для расширения. Могу ли я использовать это как замену?

Теги:
xml-parsing
sax

1 ответ

2
Лучший ответ

Вместо 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);
    }
}

Ещё вопросы

Сообщество Overcoder
Наверх
Меню