我正在使用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 = "<!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
类要扩展。我可以将其作为直接替代品吗?
答案 0 :(得分:2)
使用具有DefaultHander方法的org.xml.sax.ext.DefaultHandler2,而不是startDTD()。
报告DTD声明的开始(如果有)。这个方法是有意的 报告DOCTYPE声明的开头;如果是文件 没有DOCTYPE声明,不会调用此方法。
通过DTDHandler或DeclHandler事件报告的所有声明 必须出现在startDTD和endDTD事件之间。声明是 假设它们属于内部DTD子集,除非它们出现 在startEntity和endEntity事件之间。评论和处理 还应在startDTD之间报告DTD的说明 和endDTD事件,按其原始顺序发生(逻辑); 它们不需要出现在相对于它们的正确位置 但是,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 = "<!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);
}
}