DTD
(Document Type Definitions,文档类型定义)
1、XML文档是一种元标记语言,即一种定义标记语言的语言。在XML中可以创建新的标记语言,这些新的标记语言(也叫标记集)要通过文档类型定义(Document Type
Definitions,DTD)来定义。
2、DTD文档是这些新的标记语言的法律性文档。如果XML文档的语法符合DTD的定义和规定,那么就称为一个合法的XML文档,否则就是非法的XML文档。
DTD定义了文档的逻辑结构,规定了文档中所使用的元素、实体、元素的属性、元素与实体之间的关系。
1、使用DTD可以提供一种统一的格式。
XML的可扩展性为文档的作者提供了很高的灵活性,可有时候需要的是统一,要求某一类文档具有相同的结构。
2、使用DTD可以保证数据交流和共享的顺利进行。
3、DTD使用户能够不依赖具体的数据就知道文档的逻辑结构。
在没有XML文档的时候,也可以根据DTD为XML文档编写样式单,编写处理程序,这样可以有效地提高工作效率。
4、使用DTD可以验证数据的有效性。
DTD对文档的逻辑结构进行了约束,这种约束可以比较宽松,也可以十分严格。可以根据DTD检查数据,以验证其是否符合规定和要求,这可以保证数据的正确和有效。
DTD中描述的基本部件是元素和属性,它们负责确定XML文档的逻辑结构。
元素表示一个信息对象,而属性表示这个对象的性质。所有元素中有且只有一个根元素,其他的元素都是它的子元素,除根元素外,每个元素都被其他元素包含,一
个元素可以有几个不同类型的子元素。
元素的基本类型大致可分为两种,一种称为简单型,另一种称为复合型。简单型具有文本数据,即可析字符数据,该类型也称为上下文中的“#PCADTA”;复合型可以包
含其他元素和文本数据。
“#PCDATA”(Parsed Character Data)表示标记的内容是可解析文本,所谓的可解析文本就是非标记文本。用“#PCDATA”规范了的元素不能再包含子元素。例如How do
you do是不包含标记的文本,而How do you <list>do</list>就不是可解析的数据类型,因为其中包含有标记<list>和</list>。另外DTD文档中不同元素定义的次序没有先后
关系,但文档的语法对大小写敏感。 “#PCDATA”的声明格式:<!ELEMENT Element_Name (#PCDATA )>
<?xml version="1.0" encoding="gb2312" ?> <!DOCTYPE bookinfo [ <!ELEMENT bookinfo (title,author,publish,price)> <!ELEMENT title (#PCDATA)> <!ELEMENT author (#PCDATA)> <!ELEMENT publish (publisher,ISBN,pubdate)> <!ELEMENT publisher (#PCDATA)> <!ELEMENT ISBN (#PCDATA)> <!ELEMENT pubdate (#PCDATA)> <!ELEMENT price (#PCDATA)> ]> <bookinfo> <title>计算机导论</title> <author>丁跃潮等</author> <publish> <publisher>高等教育出版社</publisher> <ISBN>7-04-014768-8</ISBN> <pubdate>2004.6</pubdate> </publish> <price>19.7</price> </bookinfo>复合:<!ELEMENT publish (publisher,ISBN,pubdate)>
<publish> <publisher>高等教育出版社</publisher> <ISBN>7-04-014768-8</ISBN> <pubdate>2004.6</pubdate> </publish>
元素的声明格式:<!ELEMENT Element_Name Element_Defination>
其中,Element_Name为声明的元素名称,Element_Defination为元素内容格式的定义。
合法的元素声明语句如:<!ELEMENT bookinfo (title,author,publish,price)> 注:下面必须要按括号里的顺序定义子元素
<!ELEMENT publisher (#PCDATA)>
其声明格式: <ELEMENT Element_Name EMPTY>
例如下面的语句:<ELEMENT hr EMPTY>
在XML中有一种针对复合元素的最为严格的设定方法,称为子元素列表的设定。这种方式下,元素都拥有哪些子元素、每个子元素出现的次数和位置都有明确的规定,在
具体文档实现时,必须严格执行。
子元素列表的设定语法如下:<!ELEMENT Element_Name(Child_Element1, Child_Element2,…)>
其中“(Child_Element1, Child_Element2,…)”部分为Element_Name所拥有的子元素列表。
有些时候,需要在两个或多个互斥的元素中进行选择。即多选一的情况,如一个人的性别可以是男或女,两者中只能有一种情况。DTD有专门的语法来处理这种情况,语
法格式如下:<!ELEMENT Element_Name(Child_Element1| Child_Element2|……)>
其中,“(Child_Element1|Child_Element2|…)”部分为选择性元素组合,具体使用时必须要在这个列表中选择其一。
a、 一个元素可能出现一次,也可能不出现。这时可通过在元素名后面加上一个“?”来实现。
b、一个元素可能不出现,也可能出现多次。这时可通过在元素名后面加上一个“*”来实现。
c、一个元素可能出现一次,也可能出现多次,但至少也要出现一次。这时可通过在元素名后面加上一个“+”来实现。
简单来讲就是元素的附加特性,在DTD中声明元素时,也必须对该元素的属性进行声明。
在DTD中,属性的声明格式:<!ATTLIST Element_name Attribute_name TYPE Default_value>
其中,<!ATTLIST>为属性声明的关键字,Element_name为元素名,Attribute_name为属性名,TYPE是属性类型,Default_value为没有设定属性值时的默认值。
在声明属性时有以下需要注意的事项。
(1) 可以多次为一个元素声明其中所包含的属性。
(2) 属性的声明在文档中的次序没有严格的要求,可位于与其相连的元素声明之前或之后。
(3) 所有元素的属性,都要在各自所对应的标记中声明。
(4) 属性有4种不同类型的默认值,可在属性声明中的Default_value部分指定:
① default:表示使用提供的默认值,default不是一个关键字,它代表一个预设的字符串。
<!ATTLIST bookinfo bookcategory("文艺"|"自然科学")"文艺" > 此例句表示当在XML文档中省略了对bookinfo元素的bookcategory属性值进行设定时,该属性的默认值
就是“文艺”。
② #REQUIRED:表示属性值必须指定。
③ #IMPLIED:表示元素的这个属性可用可不用。
④ #FIXED:表示元素的这个属性值是一个固定值,且必须是指定的值。
CDATA型表明属性值为不包含“<”和“"”的任意字符串,如果属性值中需要包含“<”和“"”,则可使用特殊字符来代替。
如果属性值并不是任意的字符串,而是在几个可能的值中进行选择,如书籍的“类别”属性,其值可为“文艺”,也可为“自然科学”,而不可能为其他情况时,则可以将书籍
的“类别”属性设定为Enumerated型。
当元素的某个属性值是不能重复时,如书籍的ISBN属性、个人的“身份证号”属性等,要定义这样的属性则需使用属性的ID类型。在一个XML文档中,所有元素的ID类型属
性的属性值必须是唯一的,不可重复,另外,一个元素不能有超过一个ID类型的属性。
IDREF为Identifier Reference的缩写,IDREF与ID类型属性的关系为子元素与父元素的关系,即IDREF类型属性的值必须是其他元素的ID类型属性的值,且该ID类型属性
的值必须在文档的其他地方被设定过。IDREFS类型属性的属性值可有多个,每一个都必须是在文档其他地方被设定了的ID类型属性的值,而这多个属性值之间用空格隔
开。
ENTITY类型的属性提供了把外部二进制形式的文件(如.jpeg、.mp3等)和外部不可解析实体链接到XML文档的功能。因此其属性值也必须为不可解析的链接外部实际数据
的通用实体名。
ENTITIES类型属性的属性值可由多个不可解析的外部实体名称组成,各实体名称之间使用空格隔开。
NMTOKEN类型的属性限定属性值是有效的XML名称,这个属性值可以由英文、数字、“.”、 “_”、“-”、“:”等组成,这里有几点需要注意。
a 、不能包括空格。
b 、以上字符中除“:”以外,其他字符都可以作为开头字符。
c 、“:”可以出现在中间,但由于它是命名域的关键字符,所以一般不提倡使用。
XML文档中引入了外部不可解析的实体后,解析器无法解析这些二进制文件,这时,就可以使用NOTATION类型的属性为这些二进制文件指定与其对应的应用软件以对
其进行处理。
实体是包含了文档片段的虚拟存储单元,可用来存储XML声明、DTD、其他形式的文本及二进制数据等。简单来讲就是一段代码或数据的代称,这个代称即为实体的名
字。
当需要在文档中引用某段代码或数据时,可以引用与这段代码或数据相对应的实体名称来代替实体的具体内容。具有正确性检查功能的XML处理器在提交文档给最终应用
程序之前或在显示文档以前,将先把所有不同的实体引用替换为与其对应的具体内容,从而构成一个结构完整的文档。
1)按照实体的具体内容来分类,实体可分为可解析与不可解析两类。
可解析实体的具体内容为简单的字符、数字、文本块;
不可解析实体的具体内容则为图片、声音等二进制文件。
2)按照逻辑存储来分类,实体可分为内部实体与外部实体两类。
内部实体的内容是在文档内部设定的;
外部实体则是一个外部独立的物理存储对象,如某个外部文件。
3)按照使用的范围来分类,实体可分为一般实体与参数实体两类。
一般实体都用来构成文档的具体内容,可出现在XML文档中,也可出现在DTD中;
参数实体只能出现在DTD中,不能出现在XML文档中。
a、内部一般实体
内部一般实体就是在文档实体内部定义和使用的实体,其内容通常是一段文本字符。这种实体要在DTD中通过DTD语句的定义,可以在XML文档中使用,也可在DTD中
使用。其定义的语法格式如下:<!ENTITY Eentity_name "Replacement" >其中,<!ENTITY>为关键字,Eentity_name为实体名称,Replacement为实体所代替的文本内
容。引用内部一般实体的方法如: &Eentity_name;
当内部一般实体在DTD中引用时,有以下几方面需注意:
(1) 不能在元素及属性的声明中引用内部一般实体,如下面的语句即为非法的:
<!ENTITY pcd (#PCDATA)>
<!ELEMENT title &pcd;>
(2) 在语句中不能出现循环,如下面的语句即为非法的:
<!ENTITY thepub "北大&pub;">
<!ENTITY pub "出版社&thepub;">
b、外部一般实体
所谓外部一般实体就是在文档实体以外定义的,要通过一个URL才能引用到的实体。外部一般实体为独立的文件,可被多个文档所引用。正因为每一个完整的XML文档都
是一个合法的实体,所以XML通过对外部一般实体的引用,可以在一个XML文档中嵌入另一个XML文档,或者将多个文档组合成一个文档。其定义的语法格式如下:
<!ENTITY Eentity_name "URL" >其中,URL为引用的外部实体的URL地址。引用外部一般实体也与引用内部一般实体的方法一样:&Eentity_name;
在引用外部一般实体时,有以下几方面需注意:(1) 因为在一个文档中需引用某些外部文件,所以该文档声明中的standalone属性不再是默认值yes,而应该为no。
(2) 作为外部一般实体的文档,若使用的是XML的默认字符集即UTF-8或UNICODE,则可以在文档头部不进行XML声明,否则,必须有XML声明,且声明时,一定要说明
ecoding属性。
c、内部参数实体
内部参数实体是指在独立的外部DTD文档的内部定义和使用的实体,其内容为仅能为DTD而非XML文档内容的书写文本。这里提到参数实体与前面所讲的一般实体是有区
别的:(1) 在引用形式上,一般实体的引用为“&Eentity_name;”,而参数实体的引用则为 “%Eentity_name;”
(2) 在引用范围上,一般实体可在XML文档中引用,也可在DTD中引用,而参数实体只可在DTD中引用。
定义内部参数实体的语法格式如下:<!ENTITY % Eentity_name "Replacement" >
d、外部参数实体
外部参数实体是指在独立的外部DTD文档的外部定义和使用的实体,外部参数实体用于将多个独立的DTD文档组合成一个大的DTD文档。定义外部参数实体的语法格式
如下: <!ENTITY % Eentity_name "URL" >
内部DTD的定义语句和XML文档在同一个文档中,且通常放置在XML文档的头部。<!DOCTYPE Root_Element_Name [
…
]>其中,<!DOCTYPE>为关键字,Root_Element_Name为根元素名,[…]部分则为内部DTD定义语句。即是一个包含内部DTD的XML文档。
外部DTD就是有关文档定义的语句都被独立出来放在一个外部文件中,对其进行独立的管理。
<!DOCTYPE Root_Element_name SYSTEM "URL">
其中,URL为外部DTD文件的相对路径或绝对路径,该语句必须置于XML文档的头部,且在XML文档处理指令中要将standalone属性值设定为no。
所谓混合DTD,即为内部DTD与外部DTD混合使用。
<?xml version="1.0" encoding="UTF-8"?> <!-- <!ELEMENT bookinfo (title,author+,((publish,price)|(price,publish))) > --> <!DOCTYPE bookinfo SYSTEM "1.dtd"> <!DOCTYPE bookinfo[ <!ELEMENT bookinfo (title,author+,(publish|price)* ) > <!ELEMENT title (#PCDATA) > <!ELEMENT author (#PCDATA) > <!ELEMENT publisher (#PCDATA) > <!ELEMENT price (#PCDATA) > <!ELEMENT publish (publisher,ISBN*) > <!ELEMENT ISBN (#PCDATA) > <!ATTLIST bookinfo id CDATA "1"> ]> <bookinfo id="001"> <title>计算机导论</title> <author>aa</author> <author>bb</author> <price>24.8</price> <publish> <publisher>高等教育出版社</publisher> <ISBN> 7-04-2112</ISBN> </publish> </bookinfo>