这些Java教程是为JDK 8编写的。本页中描述的示例和实践不利用后续版本中引入的改进,并且可能使用不再可用的技术。
有关Java SE 9及其后续版本中更新的语言特性的摘要,请参见Java语言变化。
有关所有JDK版本的新功能、增强功能以及已删除或已弃用选项的信息,请参见JDK发行说明。
到目前为止,您已经学习了许多XML的概念,包括DTD和外部实体。您还学习了如何使用SAX解析器。本课程的剩余部分涵盖了高级主题,只有在编写基于SAX的应用程序时才需要理解。如果您的主要目标是编写基于DOM的应用程序,则可以跳转到文档对象模型。
之前您看到过,如果您将文本输出为XML,您需要知道自己是否在CDATA节内。如果是,尖括号(<)和和符号(&)应该保持不变输出。但是如果不在CDATA节内,它们应该被预定义的实体<和&替换。但是您如何知道自己是否在处理CDATA节呢?
另外,如果您正在以某种方式过滤XML,则希望传递注释。通常,解析器会忽略注释。那么您如何获取注释以便可以回显它们呢?
本节回答了这些问题。它向您展示了如何使用org.xml.sax.ext.LexicalHandler来识别注释、CDATA节和对已解析实体的引用。
注释、CDATA标签和对已解析实体的引用构成了词法信息-即关于XML文本本身的信息,而不是XML的信息内容。大多数应用程序当然只关心XML文档的内容。这样的应用程序将不使用LexicalEventListener API。但是输出XML文本的应用程序将发现它非常有用。
注意 - 词法事件处理是一个可选的解析器功能。解析器实现不必支持它(参考实现支持)。本讨论假设您的解析器支持它。
要在SAX解析器看到词法信息时得到通知,您需要使用一个LexicalHandler配置底层解析器的XmlReader。LexicalHandler接口定义了以下事件处理方法。
将注释传递给应用程序。
告诉您应用程序CDATA节开始和结束的时候,这样您就知道下一次调用characters()时可以期望什么样的字符。
给出已解析实体的名称。
告诉您DTD正在被处理,并标识它。
要激活Lexical Handler,您的应用程序必须扩展DefaultHandler并实现LexicalHandler接口。然后,您必须配置您的XMLReader实例以将解析器委托给它,并配置它将词法事件发送到您的词法处理程序,如下所示。
// ... SAXParser saxParser = factory.newSAXParser(); XMLReader xmlReader = saxParser.getXMLReader(); xmlReader.setProperty("http://xml.org/sax/properties/lexical-handler", handler); // ...
在这里,你使用XMLReader类中定义的setProperty()方法来配置XMLReader。属性名是作为SAX标准的一部分定义的,即URN:http://xml.org/sax/properties/lexical-handler。
最后,添加以下代码来定义实现接口的适当方法。
// ... public void warning(SAXParseException err) { // ... } public void comment(char[] ch, int start, int length) throws SAXException { // ... } public void startCDATA() throws SAXException { // ... } public void endCDATA() throws SAXException { // ... } public void startEntity(String name) throws SAXException { // ... } public void endEntity(String name) throws SAXException { // ... } public void startDTD(String name, String publicId, String systemId) throws SAXException { // ... } public void endDTD() throws SAXException { // ... } private void echoText() { // ... } // ...
此代码将将你的解析应用程序转换为一个词法处理器。只需给这些新方法中的每一个指定要执行的操作即可。