3.7 定义实体

所谓实体引用就是用一个字符串代替另一个字符串。这种定义方式有点类似于C语言里的宏变量。定义实体有如下作用:

alt 提高代码复用,方便修改、维护XML文档。

alt 使用某些特殊的符号,这些特殊的符号可能会使XML解析器混淆。例如小于符号(<)等。

alt 减少字符输入量,如果某个字符串特别长,而且需要经常使用,则可以将其定义为实体。

定义了实体后,该实体既可以在XML文档中引用,也可以在DTD本身中引用。但用于XML文档内的实体和用于DTD内的实体的定义和使用都不相同。下面依次介绍这两种情形。

3.7.1 定义实体

普通实体是在XML文档里使用的实体,定义普通实体的语法格式如下:

alt

使用实体的语法格式如下:

alt


alt注意

在XML文档中引用实体时,必须以&开始,以英文分号(;)结束。


定义了可在XML文档中使用的实体后,该实体既可以作为某个XML元素的字符串值使用,也可以作为某个XML元素的属性值使用。

看下面的DTD文档,其中使用实体定义了2个字符串短语:

程序清单:codes\03\3.7\entityinxml.dtd

alt

上面的DTD中定义了java和jee两个实体,其中java代表“疯狂Java讲义”字符串,而jee则代表“轻量级Java EE企业应用实战”字符串,接下来就可以在XML文档中使用这两个实体了。

下面的XML文档里<书名…/>元素的内容使用了java和jee两个实体:

程序清单:codes\03\3.7\entityinxml.xml

alt

由于DTD中定义了java实体的值为“疯狂Java讲义”,jee实体的值为“轻量级Java EE企业应用实战”,因此用浏览器来浏览上面的entityinxml.xml文档将看到图3.3所示结果。

alt

图3.3 在XML文档中引用实体

大多数时候,程序员自己定义实体都是为了减少字符输入,因为常见的特殊符号,例如小于符号、大于符号等,已经被系统定义成了实体。


alt注意

读者用Firefox、Opera等浏览器浏览上面的XML文档时可能看不到正确的结果,这是因为这两种浏览器对实体引用支持得不好,与XML文档本身无关。如果使用专业的XML处理程序或我们自己写程序来处理XML文档,则实体引用都是有效的。


3.7.2 定义参数实体

还有一种实体只能在DTD中使用,这种实体被称为参数实体,定义和使用参数实体与普通实体有小小的差别。定义参数实体的语法格式如下:

alt

在DTD中引用参数实体的语法格式如下:

alt


alt注意

在DTD文档中使用参数实体时,必须以英文百分号(%)开始,以英文分号(;)结束。与定义普通实体相比,定义参数实体需要多使用一个百分号(%)。


在上面定义的DTD文档中,对于枚举类型的属性值,假设总是允许出现true、false、yes和no这4个值,因此常常需要定义这4个值组成的枚举类型,则可以将其定义成一个参数实体。将上面的DTD文档定义成如下格式也是有效的:

程序清单:codes\03\3.7\entityindtd.dtd

alt

必须指出的是,如果需要在DTD中使用参数实体,参数实体必须前向定义。即在使用boolean参数实体之前,必须已经定义过该参数实体。如果颠倒了定义和使用的顺序,将是错误的,即使对于如下片段:

alt

上面关于boolean参数实体的定义和使用顺序是颠倒的,必须先定义参数实体,然后才能使用参数实体。


alt注意

DTD中使用的参数实体必须前向定义,也就是说必须先定义参数实体,然后才能使用该参数实体。


3.7.3 外部实体

经过前面的介绍,读者应该已经大致掌握了实体的用法:类似于定义宏变量,也就是为一段字符数据起一个短名。前面定义实体时都直接为实体指定了对应值,这种方式定义的实体称为内部实体。

与内部实体相对的是外部实体,定义外部实体的语法格式如下:

alt

从上述语法格式可以看出,外部实体的值不在DTD中直接指定,而是专门提供一个文件为该实体指定值——也就是由上述语法格式中“实体值所在文件的URI”处的文件来指定。

假设有如下XML文档:

程序清单:codes\03\3.7\outerentity.xml

alt

乍一看上去,上面<书名…/>元素的内容是普通字符数据,但实际上该元素可以包含子元素——这取决于outer实体所代表的内容。假设有如下DTD定义:

程序清单:codes\03\3.7\outerentity.dtd

alt

上面的粗体字代码定义了一个外部实体outer,该实体的值保存在myentity.txt文件中,myentity.txt文件是个普通文本文件,其内容如下:

程序清单:codes\03\3.7\myentity.txt

alt

从上面的代码可以看出:外部实体对应的文件可以拥有一个文本声明,它类似于XML声明,但可以省略version属性,且不需要指定standalone属性。而outerentity.xml文件中的outer实体代表的值将由该文件的内容代替,使用浏览器浏览outerentity.xml文件将看到图3.4所示结果。

alt

图3.4 使用外部实体

定义外部实体时除了可使用SYSTEM关键字之外,还可以使用PUBLIC关键字,用于定义公用的实体,其语法格式如下:

alt

从上述语法格式可以看出,这与使用PUBLIC关键字引入公用DTD的语法格式类似。

3.7.4 外部参数实体

类似于定义内部实体时可增加百分号(%)用于定义内部参数实体,定义外部实体时也可增加%用于定义外部参数实体。定义外部参数实体的语法格式如下:

alt

其中SYSTEM或PUBLIC的用法与前面定义外部实体时完全相似,看下面的DTD文档:

程序清单:codes\03\3.7\outerentityindtd.dtd

alt

接下来应该通过myprops.txt为outer_props参数实体指定值,下面是myprops.txt文件的内容:

alt

由上面的文件内容可以看出,<书名…/>元素的islast属性的默认值是“是”。