使用SAX获取DOCTYPE详细信息(JDK 7)

我正在使用JDK7附带的SAX解析器。 我试图抓住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 = ""; 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 ,使用具有startDTD()方法的org.xml.sax.ext.DefaultHandler2 。

报告DTD声明的开始(如果有)。 此方法旨在报告DOCTYPE声明的开头; 如果文档没有DOCTYPE声明,则不会调用此方法。

通过DTDHandler或DeclHandler事件报告的所有声明必须出现在startDTD和endDTD事件之间。 假定声明属于内部DTD子集,除非它们出现在startEntity和endEntity事件之间。 还应在startDTD和endDTD事件之间以(逻辑)发生的原始顺序报告来自DTD的注释和处理指令; 但是,它们不需要出现在相对于DTDHandler或DeclHandler事件的正确位置。

请注意,start / endDTD事件将出现在ContentHandler的start / endDocument事件中以及第一个startElement事件之前。

但是,您还必须为XML Reader设置LexicalHandler。

 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 = ""; 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); } }