可以看到,xml文档和它们的不同版本的原理性的书籍都采用自身的风格。这些自身风格有时候也会成为绊脚石,你不得不以摘要和重用的方式来描述它们。其中一个解决方法是使用通用的xml实体来描述普通的、可重用的xml成分。
实体是一个不明确的词语,它被使用于程序中以代表xml文档中一个自定义的特定的种类。
一个实体与xml文档中被命名的数据有关。你应该已经熟悉一些实体,比如&(这一个实体代表着一个记号名称)。如果使用不当,这一实体将会产生一系列的问题。
xml实体的分类有三种,如表A所示。实体通过使用“实体引用(entity references)”与xml文档相联系,也就是使用基本记号&,然后在其后面跟随着实体名称,接着是一个分号(;)。在以上的范例中,我们引用了&记号作为一个实体──实体的名称为amp,及它所指的数据是一个记号字符。
TABLE A: Entity categorizations Parsed Unparsed; Internal Extemal; General Parameter;
|
xml分解器将尽可能地将实体引用分解到它们置换的文本。这一过程的其中一部分使用DTD来查找内部实体的定义。你的实体很有可能没有被定义,但已经在DTD中被引用,如果这样,它们都属于外部实体。当SAX分解文档时,它们需要分解这些外部实体,你也可以使用EntityResolver界面来截取这一过程。
EntityResolver界面非常简单,并且很容易使用。界面包括一个名为resolveEntity的简单方法,其包含两个参数:公用的标识符(identifier)和系统标识符。这些标识符可以通过DTD中的实体定义而提供,如表A中的范例所示。
表A: entity.dtd
<!ENTITY MyCustomEntity
PUBLIC "-//Builder.com//TEXT
MyCustomEntity//EN"
"http://www.builder.com/xml/entities/MyCustomEntity">
<!ELEMENTCustomEntity (#PCDATA)>
<!ELEMENT Entity (CustomEntity)>
范例中的xml文档可参见于表B。这一文档说明了DTD用于校验的用法,并显示将MyCustomEntity作为CustomEntity成分的值。
表B: entity.xml
<?xml version="1.0" ?>
<!DOCTYPE entity SYSTEM "entity.dtd">
<Entity>
<CustomEntity>&MyCustomEntity;</CustomEntity>
</Entity>
为了使用通用的解答器(resolver)来处理这一实体,我们需要编写一个SAX分解器,SAX分解器的一个句柄,以及一个EntityResolver。EntityResolver类包含在表C中。
表C:CustomResolver.Java
import Java.io.StringReader;
import org.xml.sax.EntityResolver;
import org.xml.sax.InputSource;
public class CustomResolver implements EntityResolver {
public InputSourceresolveEntity (String publicId, String systemId)
{
StringReaderstrReader = new StringReader("This
is a custom
entity");
if
(systemId.equals("http://www.builder.com/xml/entities/MyCus
tomEntity")) {
System.out.println("Resolving
entity: " + publicId);
return new InputSource(strReader);
} else {
return null;
}
}
}