# 使用 DTDHandler 和 EntityResolver

> 原文： [https://docs.oracle.com/javase/tutorial/jaxp/sax/using.html](https://docs.oracle.com/javase/tutorial/jaxp/sax/using.html)

本节介绍剩余的两个 SAX 事件处理程序： `DTDHandler` 和 `EntityResolver` 。当 DTD 遇到未解析的实体或符号声明时，将调用 `DTDHandler` 。当必须将 URN（公共 ID）解析为 URL（系统 ID）时， `EntityResolver` 才会起作用。

## `DTDHandler` API

[选择解析器实现](validation.html)显示了一种使用 MIME 数据类型引用包含二进制数据（如图像文件）的文件的方法。这是最简单，最易扩展的机制。但是，为了与较旧的 SGML 样式数据兼容，还可以定义未分析的实体。

`NDATA` 关键字定义了一个未解析的实体：

`&lt;!ENTITY myEntity SYSTEM "..URL.." NDATA gif&gt;`

`NDATA` 关键字表示此实体中的数据不是可解析的 XML 数据，而是使用其他符号的数据。在这种情况下，符号被命名为 `gif` 。然后，DTD 必须包含该表示法的声明，如下所示。

`&lt;!NOTATION gif SYSTEM "..URL.."&gt;`

当解析器看到未解析的实体或符号声明时，除了使用 `DTDHandler` 接口将其传递给应用程序之外，它不会对信息执行任何操作。该接口定义了两种方法。

*   `notationDecl（String name，String publicId，String systemId）`

*   `unparsedEntityDecl（String name，String publicId，String systemId，String notationName`

`notationDecl` 方法传递符号的名称以及公共或系统标识符，或两者，具体取决于在 DTD 中声明的内容。 `unparsedEntityDecl` 方法传递实体的名称，适当的标识符以及它使用的表示法的名称。

* * *

**注 -** `DTDHandler` 接口由 `DefaultHandler` 类实现。

* * *

符号也可用于属性声明。例如，以下声明需要 GIF 和 PNG 图像文件格式的符号。

```
<!ENTITY image EMPTY>
<!ATTLIST image ...  type  NOTATION  (gif | png) "gif">

```

这里，类型被声明为 gif 或 png。如果两者都没有指定，则默认值为 gif。

无论使用符号引用来描述未解析的实体还是属性，都应由应用程序进行适当的处​​理。解析器对符号的语义一无所知。它只传递声明。

## `EntityResolver` API

`EntityResolver` API 允许您将公共 ID（URN）转换为系统 ID（URL）。您的应用程序可能需要这样做，例如，将 `href =“urn：/ someName”`之类的内容转换为`“http：// someURL”`。

`EntityResolver` 接口定义了一个方法：

`resolveEntity(String publicId, String systemId)`

此方法返回 `InputSource` 对象，该对象可用于访问实体的内容。将 URL 转换为 `InputSource` 非常简单。但是，作为系统 ID 传递的 URL 将是原始文档的位置，该位置很可能不在 Web 上的某个位置。要访问本地副本（如果有），您必须在系统的某个位置维护一个目录，该目录将名称（公共 ID）映射到本地 URL。