这是一个大多数 SAX 应用程序实施的主要接口:如果需要通知应用程序基本解析事件,则它将实现此接口并且使用 setContentHandler
方法,向 SAX 解析器注册一个实例。解析器将使用该实例报告与基本文档相关的事件,如启动和终止元素与字符数据。
在此接口中的事件顺序非常重要,它本身可镜像文档中信息的顺序。例如,在 startElement 事件与相应的 endElement 事件之间,元素的所有内容(字符数据、处理指令和/ 或子元素)都将以一定顺序出现。
此接口与现在不推荐使用的 SAX 1.0 DocumentHandler 接口相似,但它增加了对名称空间和报告跳过的实体(在非验证的 XML 处理器中)的支持。
实现者应该注意,在 java.net
包中还有一个 ContentHandler
类;这意味着以下实现方法可能并非明智之举
import java.net.*;
import org.xml.sax.*;
实际上,不管怎样 "import ...*" 通常标志不简洁的编程,因此,用户应该将此作为一种功能而不是错误。
以下是其主要的方法:
void setDocumentLocator(Locator locator)
强烈建议(但不是绝对需要)使用 SAX 解析器来提供定位器:如果是这样,则必须在调用 ContentHandler 接口中的任何其他方法之前调用此方法为应用程序提供定位器。
定位器允许应用程序确定任何与文档相关的事件的终止位置,即便是解析器不报告错误也是如此。通常情况下,应用程序将使用此信息报告它自己的错误(例如与应用程序的业务规则不匹配的字符内容)。由定位器返回的信息可能不足以供搜索引擎使用。
注意,该定位器仅在调用 SAX 事件回调期间,在 startDocument
返回之后,调用 endDocument
之前,返回正确的信息。应用程序不应该尝试在任何时间都使用它。
locator
- 可以返回任何 SAX 文档事件位置的对象
Locator
void startDocument() throws SAXException
在其他任何事件回调(不包括 setDocumentLocator
)之前,SAX 解析器仅调用此方法一次。
SAXException
- 任何 SAX 异常,可能包装另外的异常
endDocument()
void endDocument() throws SAXException
在此方法的说明和 ErrorHandler.fatalError(org.xml.sax.SAXParseException)
的说明之间存在着明显的冲突。在未来的主版本中解决这一不明确问题之后,关于解析器报告 fatalError() 或抛出异常后是否调用 endDocument() 这一点,客户将会十分明确。
SAX 解析器仅调用此方法一次,并且它将是解析期间最后调用的方法。直到解析器放弃解析(由于不可恢复的错误)或到达输入的结尾时,它才可以调用此方法。
SAXException
- 任何 SAX 异常,可能包装另外的异常
startDocument()
void startPrefixMapping(String prefix, String uri) throws SAXException
此事件的信息对于常规的名称空间处理并非必需:当 http://xml.org/sax/features/namespaces
功能为true(默认)时,SAX XML 读取器将自动替换元素和属性名称的前缀。
但是,有这样几种情况,应用程序需要在字符数据或属性值中使用前缀,但在这里,前缀不能自动地安全扩展;必要时,start/endPrefixMapping 事件将为应用程序提供所需信息,以便应用程序本身可在这些上下文中扩展前缀。
注意,不能保证 start/endPrefixMapping 事件相互之间能够正确地嵌套:所有的 startPrefixMapping 事件将在相应的 startElement
事件之前立即发生,所有的 endPrefixMapping
事件将在相应的 endElement
事件之后立即发生,但在其他情况下不能保证其顺序。
对于 "xml" 前缀,永远不应有 start/endPrefixMapping 事件,因为它是预声明的和不可改变。
prefix
- 声明的名称空间前缀。对于没有前缀的默认元素名称空间,使用空字符串。
uri
- 将前缀映射到的名称空间 URI
SAXException
- 客户端可能会在处理期间抛出一个异常
endPrefixMapping(java.lang.String)
,
startElement(java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes)
void endPrefixMapping(String prefix) throws SAXException
详细信息请参阅 startPrefixMapping
。这些事件将始终在相应的 endElement
事件之后立即发生,但在其他情况下 endPrefixMapping
事件的顺序不能保证。
prefix
- 被映射的前缀。当默认的映射范围结束时,这是一个空字符串。
SAXException
- 客户端可能会在处理期间抛出一个异常
startPrefixMapping(java.lang.String, java.lang.String)
,
endElement(java.lang.String, java.lang.String, java.lang.String)
void startElement(String uri, String localName, String qName, Attributes atts) throwsSAXException
解析器在 XML 文档中的每个元素的开始调用此方法;对于每个 startElement 事件都将有相应的endElement
事件(即使该元素为空时)。所有元素的内容都将在相应的 endElement 事件之前顺序地报告。
此事件允许每个元素最多有以下三个名称组件:
可以提供它们中的部分或全部,具体如何取决于 http://xml.org/sax/features/namespaces 和http://xml.org/sax/features/namespace-prefixes 属性的值:
注意,所提供的属性列表仅包括具有显式值(指定的或默认的)的属性:将忽略 #IMPLIED 属性。仅在http://xml.org/sax/features/namespace-prefixes
属性为 true (默认情况下为 false,并且对 true 值的支持是可选项)时属性列表才包括用于名称空间声明(xmlns* 属性)的属性。
与 characters()
一样,属性值可以具有需要不止一个 char
值的字符。
uri
- 名称空间 URI,如果元素没有名称空间 URI,或者未执行名称空间处理,则为空字符串
localName
- 本地名称(不带前缀),如果未执行名称空间处理,则为空字符串
qName
- 限定名(带有前缀),如果限定名不可用,则为空字符串
atts
- 连接到元素上的属性。如果没有属性,则它将是空 Attributes 对象。在 startElement 返回后,此对象的值是未定义的
SAXException
- 任何 SAX 异常,可能包装另外的异常
endElement(java.lang.String, java.lang.String, java.lang.String)
,
Attributes
,
AttributesImpl
void endElement(String uri, String localName, String qName) throws SAXException
SAX 解析器会在 XML 文档中每个元素的末尾调用此方法;对于每个 endElement 事件都将有相应的startElement
事件(即使该元素为空时)。
有关名称的信息,请参见 startElement。
uri
- 名称空间 URI,如果元素没有名称空间 URI,或者未执行名称空间处理,则为空字符串
localName
- 本地名称(不带前缀),如果未执行名称空间处理,则为空字符串
qName
- 限定的 XML 名称(带前缀),如果限定名不可用,则为空字符串
SAXException
- 任何 SAX 异常,可能包装另外的异常
void characters(char[] ch, int start, int length) throws SAXException
解析器将调用此方法来报告字符数据的每个存储块。SAX 解析器能够用单个存储块返回所有的连续字符数据,或者可以将该数据拆分成几个存储块;但是,任何单个事件中的全部字符都必须来自同一个外部实体,以便定位器能够提供有用的信息。
应用程序不能尝试在指定的范围外从数组中读取数据。
单独的字符可以由不止一个 Java char
值组成。由于不能仅用十六位来表示字符,所以发生此情况的重要情形有两种。一种情形是,字符用代理项对 表示,使用两个特殊的 Unicode 值。此类字符在所谓的 "Astral Planes" 中,代码点在 U+FFFF 之上。另一种情形涉及到复合字符,如由一个或多个重音字符构成的基本字符。
编写代码时不能假定一次读入一个 char
的算法将适用于字符单元;在某些情况下这些算法将拆分一些字符。这与在什么情况下 XML 允许有任意字符(如属性值、处理指令数据、注解以及从此方法中报告的数据)相关。通常还与 Java 代码控制国际化的文本时相关;该问题不是 XML 独有的。
注意,有些解析器将使用 ignorableWhitespace
方法而不是此方法报告元素内容中的空白(验证解析器必须 这么做)。
ch
- 来自 XML 文档的字符
start
- 数组中的开始位置
length
- 从数组中读取的字符的个数
SAXException
- 任何 SAX 异常,可能包装另外的异常
ignorableWhitespace(char[], int, int)
,
Locator
void ignorableWhitespace(char[] ch, int start, int length) throws SAXException
验证解析器必须使用此方法来报告元素内容中的每块空白(请参阅“W3C XML 1.0 Recommendation”中的 2.10 节):如果非验证解析器能够解析和使用内容模块,则这些非验证解析器也可以使用此方法。
SAX 解析器能够用单个存储块返回所有的连续空白,或者可以将该数据拆分成几个存储块;但是,任何单个事件中的全部字符都必须来自同一个外部实体,以便定位器能够提供有用的信息。
应用程序不能尝试在指定的范围外从数组中读取数据。
ch
- 来自 XML 文档的字符
start
- 数组中的开始位置
length
- 从数组中读取的字符的个数
SAXException
- 任何 SAX 异常,可能包装另外的异常
characters(char[], int, int)
void processingInstruction(String target, String data) throws SAXException
解析器将为找到的每个处理指令调用一次此方法:注意,处理指令可以出现在主要文档元素的前面或后面。
SAX 解析器必须从不使用此方法报告 XML 声明(XML 1.0 的 2.8 节)或文本声明(XML 1.0 的 4.3.1 节)。
与 characters()
一样,处理指令数据可以具有需要不止一个 char
值的字符。
target
- 处理指令目标
data
- 处理指令数据,如果未提供,则为 null。该数据不包括将其与目标分开的任何空白
SAXException
- 任何 SAX 异常,可能包装另外的异常。
void skippedEntity(String name) throws SAXException
解析器将在每次跳过实体时调用此方法。如果非验证处理器尚未看到声明,则可以跳过实体(例如,因为该实体在外部 DTD 子集中声明)。所有的处理器都可以跳过外部实体,但具体情况取决于http://xml.org/sax/features/external-general-entities
和 http://xml.org/sax/features/external-parameter-entities
属性的值。
name
- 所跳过的实体的名称。如果它是参数实体,则名称将以 '%' 开头,如果它是外部 DTD 子集,则将是字符串 "[dtd]"
SAXException
- 任何 SAX 异常,可能包装另外的异常