文档

Java™教程
隐藏目录
处理词法事件
导航: Java XML处理API(JAXP)
课程: XML的简单API

处理词法事件

到目前为止,您已经学习了许多XML的概念,包括DTD和外部实体。您还学习了如何使用SAX解析器。本课程的剩余部分涵盖了高级主题,只有在编写基于SAX的应用程序时才需要理解。如果您的主要目标是编写基于DOM的应用程序,则可以跳转到文档对象模型

之前您看到过,如果您将文本输出为XML,您需要知道自己是否在CDATA节内。如果是,尖括号(<)和和符号(&)应该保持不变输出。但是如果不在CDATA节内,它们应该被预定义的实体&lt;&amp;替换。但是您如何知道自己是否在处理CDATA节呢?

另外,如果您正在以某种方式过滤XML,则希望传递注释。通常,解析器会忽略注释。那么您如何获取注释以便可以回显它们呢?

本节回答了这些问题。它向您展示了如何使用org.xml.sax.ext.LexicalHandler来识别注释、CDATA节和对已解析实体的引用。

注释、CDATA标签和对已解析实体的引用构成了词法信息-即关于XML文本本身的信息,而不是XML的信息内容。大多数应用程序当然只关心XML文档的内容。这样的应用程序将不使用LexicalEventListener API。但是输出XML文本的应用程序将发现它非常有用。


注意 - 词法事件处理是一个可选的解析器功能。解析器实现不必支持它(参考实现支持)。本讨论假设您的解析器支持它。


LexicalHandler的工作原理

要在SAX解析器看到词法信息时得到通知,您需要使用一个LexicalHandler配置底层解析器的XmlReader。LexicalHandler接口定义了以下事件处理方法。

comment(String comment)

将注释传递给应用程序。

startCDATA(), endCDATA()

告诉您应用程序CDATA节开始和结束的时候,这样您就知道下一次调用characters()时可以期望什么样的字符。

startEntity(String name), endEntity(String name)

给出已解析实体的名称。

startDTD(String name, String publicId, String systemId), endDTD()

告诉您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() {
    // ...
}

// ...

此代码将将你的解析应用程序转换为一个词法处理器。只需给这些新方法中的每一个指定要执行的操作即可。


上一页: 实施SAX验证
下一页: 使用DTDHandlerEntityResolver