Tech view for DTD1
author:tuiye@126.com
符合标准(Well-formed)的站点,第一件事情就是声明符合自己需要的DOCTYPE。DOCTYPE是document type(文档类型)的简写,用来说明你用的XHTML或者HTML是什么版本。DOCTYPE声明是必不可少的关键组成部分;除非你的XHTML确定了一个正确的DOCTYPE,否则你的标识和CSS都不会生效。
当然存在许多(X)HTML的类型,所有这些类型都以相应的W3C规范来定义,如HTML 4.01 Strict,HTML 4.01 Transitional, XHTML 1.0 Strict等。这些类型的定义就是DTD(Document Type Definition)。
在处理HTML文档时,需要知道(X)HTML用的是那种DTD,因此常在(X)THML的开始就声明一个DTD2,如下图:
以上的声明的DTD类型是一个Browser或其他处理HTML工具的关键信息。这样即加快了Browser等工具“理解”(Understanding)与显示的速度,也避免了不必要的处理出错。
DTD可以看作是一个模板,规定了相应文档中存在的元素、元素具有的属性、在元素内部元素的层次结构以及元素在整个文档中出现的顺序。DOCTYPE声明指出阅读程序应该用什么规则集来解释文档中的标记,Validate相应的文档。在Web文档的情况下,“阅读程序”通常是浏览器或者校验器这样的一个程序,“规则”则是W3C所发布的一个文档类型定义(DTD)中包含的规则。
使用DTD的好处:
-
提供资料格式一致性描述
-
验证资料的正确性
-
资料自动化处理
-
促进专业分工
-
提供更好的建构功能
用了DTD,使得:
a)使用DTD,我们每个XML文件都可以有自己的格式描述
b)使用DTD,独立的组织间可以用公用的DTD交换数据
c)在你的应用中可以用DTD检验你从外界得到的数据是否有效
DTD的一些说明如下,注意1)关键词大小写有别(Case Sensitive);2)空格有别(Space):
-
文体声明(Doc Type Declaration)
<!DOCTYPE root [DTD]>
<!DOCTYPE root SYSTEM URL>
<!DOCTYPE root PUBLIC FPI-identifier URL>
root是XML/HTML等文档的根节点,例如HTML文档的root为html
a) 文体声明必须在文件实体之前
b) 每个只可以出现一个文体声明
c) 所有元素需在DTD中定义
d) DTD可以内部声明,也可外部声明
-
注释(COMMENT)
与一般的HTML的注释一样,以 <!-- 符号开始,--> 符号结束。两个符号间的所有语句将被忽略,注释语句不能嵌套。
e.g.
<!-- this is a comment -->
-
实体(ENTITY)
实体把一个名称与一组字符串关联起来,当适用实体时,解析器都会使用相对应的字符串替换该实体的名称。实体分为:
-
可进行解析的(parsed)实体
-
通用(general)实体/一般实体,用于XML文档中
-
参数(parameter)实体,XML DTD中
-
-
不可进行解析的(unparsed)实体
-
每一个未解析实体都有一个相关联的用符号名称标识的符号(Notation)
可解析的实体将被解析器处理,而且绝大多数实体是可解析的;而不可解析的实体将被解析器忽略,他们基本被保留用于某些标签的属性列表,它是标签属性值可替换的字符串。
当然还可以按实体内容的位置可以分,两种:
– 内部实体(Internal Entity):实体内容在实体声明中给出。
– 外部实体(External Entity):实体内容在声明之外,例如另外一个文件。
e.g.
通用实体:
例如版权符号(©)的实体就是 © ,还有XML预先定义的5种最普通的通用实体
& &
' ’
> >
< <
" “
-
内部通用实体
1)定义:<!ENTITY entity_name "entity_content"> 或
<!ENTITY entity_name 'entity_content'>
内容只能是字符数据。
2)引用:&entity_name;
要注意这里的&和;都是半角字符。
还有,实体的引用不能出现循环,而且不能用在元素和属性的声明中。
-
外部通用实体
1) 定义:<!ENTITY entity_name SYSTEM "entity_URI">
<!ENTITY entity_name PUBLIC "PublicIdentifier" "entity_URI">
2) 引用:&entity_name;
3) 注意:引用外部实体的时候,在主文档中,必须把外部实体文档的元素、属性等都加以定义。
参数实体:名称前带有一个百分号(%)
%告知解析器在DTD参数实体中寻找实体名称,然后将实体值插入到DTD中调用实体位置,最后将实体值作为DTD一部分进行处理。
参数实体是DTD的主体,没有它们,创建DTD变的十分困难3。
实体声明如下:
通用实体 :<!ENTITY name value>
参数实体 :<!ENTITY % name value>
name4,value5都有自己的命名与引用的注意点。%前后都是空白的
我们还可以引入公共文档,如下:
%HTMLlat1;
表明所有这些通用实体都被定义作为语言的一部分。
关键词NDATA可以来声明一个不能进行解析的实体。
a) 内部参数实体
1) 定义:<!ENTITY % entity_name "entity_content"> 或
<!ENTITY % entity_name 'entity_content'>
2) 引用:%entity_name;
3) 注意:实体的内容不但可以包括文本,还可以包括标记。参数实体只能用于外部DTD,而不能用于xml文档或者内部的DTD。使用内部参数实体可以提高创建DTD的效率,还可以便于批量修改。
b)外部参数实体
外部参数实体用于将多个DTD文档组合成一个完整的DTD。
1) 定义:<!ENTITY % entity_name SYSTEM "entity_URI">
<!ENTITY % entity_name PUBLIC "PublicIdentifier" "entity_URI">
2) 引用:%entity_name;
3) 注意:每一个外部DTD文档都必须有一个声明,说明使用的字符集。所有的DTD文档都要是一个完整的DTD定义。
实体的优先顺序:
a) 如在同一份DTD中声明了名称相同的ENTITY,则使用第一个ENTITY;
b) 如有内外DTD的声明名称相同的ENTITY,则使用内部声明的ENTITY。
-
元素(ELEMENT)
定义如下:
元素声明:<!ELEMENT name Type>
其中Type包括EMPTY、ANY、ELEMENT、MIXED,也可以省略。
EMPTY表示不包含任何数据内容,但是可以有属性。
ANY表示包含任何xml允许的内容。
ElEMENT表示只包含子元素。
MIXED表示允许元素包含子元素和数据内容。
子元素的定义:<!ElEMENT element_name ControlName>
控制方式有如下几种:
( )和, +和* ,?和| 说明在下表
混合型元素:
<!ElEMENT F_Element (#PCDATA|E_Element)*>
<!ElEMENT E_Element (子元素定义)>
元素类型一共有两种,一种是简单类型,只包含文本数据(#PCDATA),另外一种是符合类型,可以包含其它元素和文本数据。
它遵循与实体一样得命名规则。
表1 CONTENT(TYPE)形式
CONTENT | 解释 |
EMPTY | 如果一个元素的CONTENT被声明为EMPTY的话,表示该元素不能包含任何子元素和文本 |
ANY | 表示该元素其中可以包含任何本身有效的元素内容,也就是说,它能够包含在DTD其他 位置已经声明过的元素 |
#PCDATA 被解析的CDATA (parsed character data)) | 表明该元素可以包含任何字符数据,但是不能在其中包含任何子元素。假设我们定义 元素美女<!ELEMENT 美女 #PCDATA>则下面的实例是正确的:<美女>人是因为可爱而美丽,但是 美丽一点也就可爱了</美女>而下面的实例就是错误的:<美女>人是因为<B>可爱<B>而美丽, 但是美丽一点也就可爱了<美女>因为在其中包含了子元素<B>。一般如果定义元素的 CONTENT为#PCDATA,最好在其中只加入纯文本字符数据。 |
包含其他类型的元素 | 最通常的情况是一个元素本身是有其他元素的集合构成的,比如下面的例子:表示运算符 号这个元素可以选择加法、减法乘法、除法四个元素中的一个作为它的内容 |
元素语法
DTD 通过元素内容模型(ECM)可以定义以下6 种的元素内容类型:
-
简单类型,即只能包含文本字符内容,且没有属性定义。
简单类型表示元素内容只能是文本字符。简单类型的元素类型声明(ETD)采用如下结构:
<!ELEMENT elementName (#PCDATA)>
b) 带有简单内容的复杂类型,即只能包含文本字符内容,但可以有属性定义。
简单内容表示只能包含合法的XML 文本字符。而复杂类型表示该元素还可以有属性。带有简单内容的复杂类型的元素类型声明(ETD)采用的结构与简单类型的一样。但是在该元素上还有属性定义,即还要在DTD 中给该元素声明属性。
c) 带有复杂内容的复杂类型,即可以包含子元素,也可以有属性定义
复杂内容表示元素可以包含其他元素作为子元素。 带有复杂内容的复杂类型的元素类型声明(ETD)采用的结构有两种:
– 逗号方式:
<!ELEMENT elementName (element1,element2,…)>
– 或符号方式:
<!ELEMENT elementName (element1 | element2 | …)>
逗号方式也叫顺序方式,表示包含的子元素在实例XML 文档中必须按照逗号分隔的顺序出现。或符号方式表示只能出现或符号“|”分隔的任一个子元素。
d) 混合内容类型,即既要包含子元素,又要包含文本字符内容,也可以有属性定义。
即有#PCDATA 内容又有子元素的元素内容类型,可以说是具有混合内容。在DTD 中,混合内容类型只能使用或符号“|”,即它的元素类型声明(ETD)只能采用如下结构:
<!ELEMENT elementName (#PCDATA | element1 | element2 | …)*>
-
空内容类型,即只可以有属性定义,不能有其他任何内容,包括文本字符及子元素。
空元素,是由空标记定义的元素,它只可能有属性定义而不会任何内容。 空内容类型的元素类型声明采用的结构是:
<!ELEMENT elementName EMPTY>
“EMPTY”关键字表示元素“elementName”不能包含任何内容,包括文本字符及元素,但是它可以有属性,即在DTD 中可以有属性声明。
-
任何内容类型,即可以包含任何合法文本字符、子元素及属性定义。
如果元素的内容类型是任何内容,表示该元素可以包含任何子元素和文本内容,而且个数也是任意的,反正一切都是任意。所以对于任何内容类型的元素,除了指定了元素的名称,元素能包含的内容可以说没有做任何定义。对应的元素类型声明采用的结构为:
<!ELEMENT elementName ANY>
表2使用量词(Quantifier)符号
-
符号
目的
例子
意义
()
括号内包含元素群组或一组可选择的内容
(内容1, 内容2)
元素必须包含一连串的内容,如内容1及
内容2
,
将一连串项目分开
并确定显示顺序
(内容1, 内容2, 内容3)
元素必须依指定的顺序
包含内容1、内容2
及内容3
|
将可选择的项目以群
组分开
(内容1|内容2|内容3)
元素必须包含内容1、
内容2及内容3其中一
项
?
?
表示项目必须出现一
次或完全不出现
内容1?
元素可能包含内容1。
如果内容1真的出现,
它也只能出现一次
*
表示项目可出现任意
次数
内容1*
元素可以包含内容1。如果内容1真的出现,它可以出 现任意次数
+
表示项目必须出现
一次或一次以上
内容1+
元素必须包含内容1。它可以出现一次或任意次数
没有任何符号
表示只有一个项目会
出现
内容1
元素必须包含内容1
e.g.
<!ELEMENT EMAIL (TO+ , FROM , CC* , SUBJECT? , BODY?)>
To元素是必要的,而且至少出现一次
From元素只能出现一次
Cc元素是选择性的,但它可以出现一次或一次以上
Subject元素是选择性的,如果出现在文件内时,只能出现一次
Body元素是选择性的,如果出现在文件内时,只能出现一次
-
元素属性(ATTLIST)
定义
<!ATTLIST elementName attributeName attributeType attributeDefaultValue>
或
<!ATTLIST elementName
attributeName1 attributeType1 attributeDefaultValue1
attributeName2 attributeType2 attributeDefaultValue2
…>
其中:"attributeType"表示属性值的类型,而"attributeDefaultValue"是属性默认值。
在附录4中有ATTLIST的范例
-
属性值
-
表3 属性值列表(Attribute Type List)
类型 | 具体的含义说明 |
CDATA | 这个类型表明该属性只能包含字符数据,比如"strong","23","美女","恐龙"等等 |
ID | 该属性的取值必须是唯一的,就象我们每个人都有的身份证号码一样。在一个文档 内两个ID属性的值一定不可以一样。 |
IDREF,IDREFS | 这个属性的值实际上就象C++中的指针一样,它是一个指向文档中其他地方声明的 ID值。所以如果具体的文档中该属性的取值和它所指向的ID值不匹配的话,就会 返回错误。IDREFS和IDREF类似,但是可以具有由空格分隔的多个引用。 |
ENTITY,ENTITIES | ENTITY属性的值必须对应一个在文档内部声明的但还没有分析过的实体。ENTITIES 属性和ENTITY类似,不同的是它可以包含多个实体,每一个实体之间可以用空格 进行分隔。需要注意的是实体包括普通实体、外部实体、参数实体和外部参数实 体。一般来说,你可以把实体理解为类似C++中的一个定义,比如在C++中,我们 定义一个变量: const MYCOMPANYNAME="BigSoft"以后你就可以在程序中 使用变量MYCOMPANYNAME。这里可以把MYCOMPANYNAME当成一个实体来理解。 |
NMTOKEN,NMTOKENS | NMTOKEN和CDATA非常类似,不同之处在于它是CDATA的一个子集。它所使用的字 符必须是字母、数字、句点[.]、破折号[-]、下划线[_]或冒号[:]。NMTOKENS和NMTOKEN类似,不同之处在于它可以包含多个值,每个值之间用空格进行分隔 |
NOTATION | NOTATION属性的值必须引用在文档中其他地方声明的某个注解的名称 |
NOTATION (enumerated) | 该属性的值必须匹配NOTATION名称列表中的某个名称,比如我们已经存在两个NOTATION,一个为beauty,一个为beast。我们可以定义一个属性类型为NOTATION(beauty | beast) |
Enumerated | 这个几乎和C++中的枚举变量一样,我们事先定义好一些值,该属性的值必须匹配 所列出的这些值。比如现在有值为美丽、泼辣、性感、智慧。该属性的类型就可以 表现为(美丽|泼辣|性感|智慧),实际内容文档必须从这些值中取一个。注意值之 间用"|"进行分隔 |
xml: | The value is a predefined xml value |
String Type: CDATA
Tokenized Type: NMTOKEN, NMTOKENS, ID, IDREF, IDREFS, ENTITY, ENTITIES
Enumerated Type: NOTATION, EMUMERATION
b)必须的和默认的属性
可以选择四种值中的一种放在属性类型的后面
表4 属性类型(Default Value)
值 | 含义 |
#REQUIRED | 用来告诉XML解析程序,该元素的所有实例都必须有该属性的值。就象数据表中某 一个字段不允许为空一样。 |
#IMPLIED | 表示如果该元素的实例中没有指定该元素的值的话,就忽略该属性。就象在数据表 中某一个字段的值可以为NULL一样。 |
#FIXED value | 表示包含该属性的元素实例必须指定所列出的值,比如一个属性名称为美女:美 女 CDATA #FIXED "我的老婆"表示如果在实例中没有列出这个属性的话,解析器依 然认为存在美女这个属性,它的值就是"我的老婆"。一般的应用是设计这个属性用 来说明这些文档都是由一个DTD来实例化产生的。 |
Default value | 为属性提供一个默认的值。比如一个属性名称为美女:美女 CDATA "我的老婆"如果 在该属性的实例中没有包含这个属性的话,解析器就认为该属性的值就是"我的老婆" ,如果在该属性的实例中包含了这个属性并赋值了的话,就采用这个赋值。 |
-
符号(Notation)
Notation主要是用来表明文档中需要来自外部源的数据,而该数据XML本身是不能进行解析的,比如各种格式的二进制文件(比如图形文件、声音文件等),需要外部的应用程序进行处理。
符号(Notation)可以用来表示非XML 数据的格式。例如,我们可以声明符号来表示那些嵌入到<picture> 元素中的二进制图像数据是JPEG 格式还是GIF 格式等。符号可以描述嵌入到XML 实例中的数据,或者在外部文件中、通过未解析实体链接到实例中的数据,即符号还可以描述未解析实体的格式。也就是说其含义为不需要解析的外部内容(例如:二进制数据)的格式声明,以及用于处理这些内容的外部应用程序。
符号的声明有3 种方式:
– 方式1:
<!NOTATION notationName SYSTEM "URIreference">
– 方式2:
<!NOTATION notationName PUBLIC "PublicIdentifier" "URIreference">
– 方式3:
<!NOTATION notationName PUBLIC "PublicIdentifier">
其中“notationName”是符号的名称,它必须是NCName(No Colon Name,即没有冒号的名称)。
“URIreference”可以是任何值,因为它的用处最终由XML 处理程序来决定。
符号与XML数据
符号可以指定XML 文档内的二进制数据的格式。
– 首先要声明一个符号来表示该格式。
– 然后在XML 元素上声明一个NOTATION 类型的属性。
– 最后通过该属性就能指出元素的二进制内容是什么格式。
符号与未解析实体
符号不仅能表示XML 数据的格式,也可以用来表示未解析的通用实体的格式
– 首先声明相应的符号来表示相应的数据格式。
– 然后声明相应的未解析的一般实体。
– 最后在相应的XML 元素上声明一个ENTITY 或ENTITIES 类型的属性。
-
通过该属性能得到该实体的内容,并在实体声明时指定了实体的数据格式
Notation主要是用来表明文档中需要来自外部源的数据,而该数据XML本身是不能进行解析的,比如各种格式的二进制文件(比如图形文件、声音文件等),需要外部的应用程序进行处理。
Notation声明的语法格式如下:
<!NOTATION NAME ExternalID>
需要注意的是NAME必须由字母、数字、句点、破折号或冒号组成,并且第一个字符必须为字母或者是下划线。下面的例子表示GIF图象作为不解析的外部内容。
<!NOTATION gif system "iexplore.exe">
<!ENTITY logo SYSTEM "http://somewebsite/somecategory/something.gif" NDATA gif>
<!-- 这里NDATA表示XML不解析该数据 -->
<!ELEMENT PIC EMPTY>
<!ATTLIST PIC
loc ENTITY #REQUIRED
>
然后,在具体的实例化文档中包含下面一行代码:
<PIC loc="&logo;" />
根据DTD定义,loc属性值是一个不解析的实体。解析器可以根据DTD定义知道这一点,然后它就不对其进行解析,也不会象解析实体一样把它包括到XML文档里面。同时,XML解析器将通知iexplore.exe该引用的存在。
-
DTD与命名空间
-
DTD不像XML Schema 那样能直接支持命名空间。
-
因为命名空间的声明在XML 实例文档中可以认为是元素的特殊属性,所以使用DTD 来定义带命名空间的XML 词汇可以通过:
-
– 在XML 文档中的命名空间声明必须要在DTD 中进行相应的属性声明。
– 所有在DTD 中需要出现元素和属性名称的地方必须是合法名称(QName),除非它不属于任何命名空间。
– 在XML 的DOCTYPE 声明中,根元素的名称也必须是合法名称。
-
条件段(Conditional Section)
<![INCLUDE [
…any content…
]]>
或
<![IGNORE [
…any content…
]]>6
或者这么定义
<!ENTITY % English "INCLUDE">
<!ENTITY % Metric "IGNORE">
然后
<! [%English [
…English stuff here…
]]>
或
<! [%Metric [
…Metric stuff here…
]]>
INCLUDE:表示包含此实体
IGNORE:表示不包含此实体
-
连接(引用)
-
内部连接
-
内部DTD 就是把DTD 定义信息跟XML 文档本身放在同一个文档里。
内部DTD 的语法格式是:
<!DOCTYPE rootElement [
declarations
]>
-
外部连接
-
外部DTD 就是DTD 定义放在了另外一个独立的文件里,而且这个文件的扩展名一般为.dtd。当一个DTD 在一个外部文件里后,我们一样可以通过XML 文档的DOCTYPE 声明来把该DTD 文件链接进来,有两种链接方式:
– 系统链接方式:
使用系统链接方式需要在DOCTYPE声明中加入SYSTEM 属性:
<!DOCTYPE rootElement SYSTEM "URIreference">
SYSTEM关键字只用于个人或组织内部的DTD文件分享。如果要引用公认的DTD,就应该使用PUBLIC关键字来引用DTD。
使用系统链接需指定要引用的DTD 文件的URI,即如果该DTD 文件不在本地机器上,需要指定完整的地址信息,包括主机名等。
– 公共链接方式:
当使用PUBLIC 关键字进行链接时,需要一个公共标识名,即:
<!DOCTYPE rootElement PUBLIC "PublicIdentifier" "URIreference">
其中“PublicIdentifier”为公共标识名(有命名规定,见附录3)
使用外部DTD 可以使它方便高效地被多个XML文档所共享。
-
即外部又内部
如果DOCTYPE 声明想即包括内部子集,又要引用外部文件或外部子集,它可以使用以下语法:
<!DOCTYPE rootElement SYSTEM "URIreference"[
declarations
]>
或者
<!DOCTYPE rootElement PUBLIC "PublicIdentifier" "URIreference"[
declarations
]>
-
附录
附录 一
下面是一个完整的DTD例子。我把另一个菜谱加入文件内,并为DTD做了注释。可以注意到我在第二个菜谱中用到子条目。
<?xml version="1.0" encoding="GB2312"?>
<!DOCTYPE cust:客户名单SYSTEM "customer.dtd"> <!—文体声明 -->
<cust:客户名单xmlns:cust="http://www.sinovo.cn/dtd/customer.dtd">
<!-- 客户甲-->
<cust:客户cust:custId="CUST_1">
<cust:名称>IBM</cust:名称>
<cust:地址>北京</cust:地址>
<cust:电话>65391187</cust:电话>
<cust:fax>65391189</cust:fax>
<emp:联系人xmlns:emp="http://www.sinovo.cn/dtd/employee.dtd">
<emp:姓名>张三</emp:姓名>
<emp:电话>
<emp:固定电话emp:type="Office">12345678</emp:固定电话>
<emp:固定电话emp:type="Home">87654321</emp:固定电话>
<emp:移动电话>13901234567</emp:移动电话>
</emp:电话>
<emp:email>zhangsan@sample.com</emp:email>
</emp:联系人>
</cust:客户>
</cust:客户名单>
<?xml version="1.0" encoding="GB2312"?>
<!ELEMENT cust:客户名单(cust:客户+)>
<!– 定义命名空间属性xmlns:cust -->
<!ATTLIST cust:客户名单xmlns:cust CDATA #IMPLIED>
<!ELEMENT cust:客户(cust:名称,cust:地址,cust:电话,cust:fax,emp:联系人)>
<!ATTLIST cust:客户cust:custId ID #REQUIRED>
<!ELEMENT cust:名称(#PCDATA)>
<!ELEMENT cust:地址(#PCDATA)>
<!ELEMENT cust:电话(#PCDATA)>
<!ELEMENT cust:fax (#PCDATA)>
<!ENTITY % contractInfo SYSTEM "contact.dtd">
%contractInfo;
<?xml version="1.0" encoding="GB2312"?>
<!ELEMENT emp:联系人(emp:姓名,emp:电话,emp:email)>
<!– 定义命名空间属性xmlns:emp -->
<!ATTLIST emp:联系人xmlns:emp CDATA #IMPLIED>
<!ELEMENT emp:姓名(#PCDATA)>
<!ELEMENT emp:电话(emp:固定电话*,emp:移动电话)>
<!ELEMENT emp:固定电话(#PCDATA)>
<!ATTLIST emp:固定电话emp:type CDATA #REQUIRED>
<!ELEMENT emp:移动电话(#PCDATA)>
<!ELEMENT emp:email (#PCDATA)>
然有DTD,文档将被检查看是否符合DTD做出的限制。换句话说,我们要保证文档的有效性。为了达到这个目的,我们需要另一个工具:有效性分析器(Validator)。
附录 二
常用DTD List:
HTML 4.01 - Strict, Transitional, Frameset:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN"
"http://www.w3.org/TR/html4/frameset.dtd">
XHTML 1.0 - Strict, Transitional, Frameset:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">
XHTML 1.1 - DTD:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
HTML 2.0 - DTD:
<!DOCTYPE html PUBLIC "-//IETF//DTD HTML 2.0//EN">HTML 3.2 - DTD:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
MathML 1.01 - DTD:
<!DOCTYPE math SYSTEM
"http://www.w3.org/Math/DTD/mathml1/mathml.dtd">
MathML 2.0 - DTD:
<!DOCTYPE math PUBLIC "-//W3C//DTD MathML 2.0//EN"
"http://www.w3.org/TR/MathML2/dtd/mathml2.dtd">
XHTML + MathML + SVG - DTD:
<!DOCTYPE html PUBLIC
"-//W3C//DTD XHTML 1.1 plus MathML 2.0 plus SVG 1.1//EN"
"http://www.w3.org/2002/04/xhtml-math-svg/xhtml-math-svg.dtd">
SVG 1.0 - DTD:
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN"
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
SVG 1.1 Full - DTD:
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
SVG 1.1 Basic - DTD:
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1 Basic//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11-basic.dtd">
SVG 1.1 Tiny - DTD:
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1 Tiny//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11-tiny.dtd">
XHTML + MathML + SVG Profile (XHTML as the host language) - DTD:
<!DOCTYPE html PUBLIC
"-//W3C//DTD XHTML 1.1 plus MathML 2.0 plus SVG 1.1//EN"
"http://www.w3.org/2002/04/xhtml-math-svg/xhtml-math-svg.dtd">
XHTML + MathML + SVG Profile (Using SVG as the host) - DTD:
<!DOCTYPE svg:svg PUBLIC
"-//W3C//DTD XHTML 1.1 plus MathML 2.0 plus SVG 1.1//EN"
"http://www.w3.org/2002/04/xhtml-math-svg/xhtml-math-svg.dtd">
附录 3
公共标识的命名规则
1) 公共标识的命名规则和XML 文件的命名规则稍有不同,具体说,公共标识名只能包含字母(非DBCS字符) 、数字、空格及下面的字符:
_ % $ # @ ( ) + : = / ! * ; ?
2)还有,公共标识名还必须符合一些标准的规定:
– ISO 组织制定的DTD 以“ISO”三个字母开头,被改进的非ISO 标准的DTD 以加号“+”开头,未被改进的非ISO 标准的DTD 以减号“-”开头。
– 无论是哪一种情况,开始部分后面都紧跟着两个斜扛“//”,然后是DTD 所有者的名称。
– 名称之后又是两个斜扛“//”,然后是该DTD 的描述信息。
– 最后,又是两个斜扛“//”,然后是语言种类。
附录 4
举一个例子用来说明属性类型IDREF/IDREFS的使用,见下面的DTD范例:
<!ELEMENT FAMILY (PERSON+)>
<!ELEMENT PERSON EMPTY>
<ATTLIST PERSON
relID ID #REQUIRED
parentID IDREFS #IMPLIED
name CDATA #REQUIRED
>
注意到这里的parentID的类型为IDREFS,这个表明该属性的值必须在文档中出现过。如果该属性的值没在文档中出现过的话,该文档就属于不规范文档,解析器就不会认为该文档是有效的。
比如下面的文档就是一个不正确的文档。
<FAMILY>
<PERSON relID="P_1" name="Joe">
<PERSON relID="P_2" name="NiEr">
<PERSON relID="P_3" name="MoZi">
< PERSON relID="P_4" parentID="P_1 P_5" name="Violet">
</FAMILY>
原因是parentID中出现了值"P_5",而这个值在没有在文档中出现过。
举一个例子用来说明属性类型NMTOKENS的使用,见下面的DTD(ex02.dtd)范例:
<!ELEMENT PERSON (NAME,FAVOURITY)>
<!ELEMENT NAME (#PCDATA)>
<!ATTLIST NAME
USERID NMTOKENS #REQUIRED
>
<!ELEMENT FAVOURITY (#PCDATA)>
<!ATTLIST FAVOURITY
FAVOURDESC NMTOKENS #REQUIRED
>
下面的文档就是一个不正确的文档:
<?xml version="1.0" encoding="GB2312" standalone="no" ?>
<!DOCTYPE PERSON SYSTEM "ex02.dtd">
<PERSON>
<NAME USERID="JOBS22@#$_tt" />
<FAVOURITY FAVOURDESC="FOOTBALL" />
</PERSON>
因为在USERID这个属性值中包含了NMTOKENS所不允许的字符"@#$"。
附录5 glossary
DOCTYPE declaration
<!DOCTYPE …>
DTD Components
Elements declaration
<!ELEMENT…>
Attributes declaration
<!ATTLIST…>
Entities declaration
<!ENTITY…>
NOTATION declaration
<!NOTATION…>
Comments
<!-- whatever is legal -->
<?xml version="1.0" standalone="no"?>
standalone="no" 因該份XML文件已引用外部DTD,所以不再是獨立存在
1 DTD : Document Type Definition
22存在很多类型的DTD,在后文附有常用的DTD List
3 类似与C中的#define宏机制,但是更加简单,仅仅为字符串的替换
4 以字母、冒号或下划线开始,不能以字符串 “XML”开始
5 实体值是引号中的一个字符串或是对其他包含实体的值的文档的调用,对于外部的实体值,URL的关键字 SYSTEM或PUBLIC
6 此方法见的比较少
1