XML DTD详解
一个有效的XML文档必然是结构正规的,结构正规的XML文档不一定是有效的,即有效的是格式正规的一个子集。
本讲详细介绍DTD,包括其对元素的定义,属性的定义,以及实体的定义
元素的定义
DTD中的修饰符号:
属性的定义:
属性类型——CDATA
<!ATTLIST title name CDATA #REQUIRED>
定义了一个属性,是属于title元素的,属性名叫name,类型是字符串(包括数字和中文),并且是一个必须要有的属性。
属性类型——ID
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE pets [ <!ELEMENT pets (dog+,penguin)> <!ELEMENT dog (id,name,health,love,strain)> <!ELEMENT penguin (id,name,health,love,sex)> <!ELEMENT id (#PCDATA)> <!ELEMENT name (#PCDATA)> <!ELEMENT health (#PCDATA)> <!ELEMENT love (#PCDATA)> <!ELEMENT strain (#PCDATA)> <!ELEMENT sex (#PCDATA)> <!ATTLIST dog id ID #REQUIRED> ]> <pets> <dog id="d01"> <id>d01</id> <name>安倍晋三</name> <health>100</health> <love>100</love> <strain>草狗</strain> </dog> <dog id="d02"> <id>d01</id> <name>安倍晋三</name> <health>100</health> <love>100</love> <strain>草狗</strain> </dog> <penguin> <id>p01</id> <name>妮妮</name> <health>100</health> <love>100</love> <sex>100</sex> </penguin> </pets>
这里<!ATTLIST dog id ID #REQUIRED> 表名dog元素有一个属性名为id,它的类型是ID,要求id不能重复
属性类型——IDREF/IDREFS
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE family [ <!ELEMENT family (person+)> <!ELEMENT person EMPTY> <!ATTLIST person relID ID #REQUIRED parentID IDREFS #IMPLIED name CDATA #REQUIRED> ]> <family> <person relID="p01" name="爸爸"/> <person relID="p02" name="妈妈"/> <person relID="p03" name="小明" parentID="p03 p02"/> </family>
从这个例子还可以看到同一个元素可以一次定义多个属性,多个属性之间用空格分隔即可。
属性类型——NMTOKEN/NMTOKENS
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE poem[ <!ELEMENT poem (title+,content)> <!ELEMENT title (#PCDATA)> <!ELEMENT content (#PCDATA)> <!ATTLIST title author NMTOKEN #REQUIRED> ]> <poem> <title author="zhangsan">001</title> <title author="李 四">001</title> <content>123</content> </poem>
以上代码有问题,李四中间加了空格
属性类型——Enumerated
实现定义好一些值,属性的值必须在所列出的值的范围内。
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE poem[ <!ELEMENT poem (title+,content)> <!ELEMENT title (#PCDATA)> <!ELEMENT content (#PCDATA)> <!ATTLIST title author (zhangsan|lisi|wangwu) #REQUIRED> ]> <poem> <title author="zhangsan">001</title> <title author="lisi">001</title> <content>123</content> </poem>
author的属性值必须在 zhangsan|lisi|wangwu 中的任意一个
属性的特点
#REQUIRED:元素的所有实例都必须有该属性的值(NOT NULL)。
语法:
<!ATTLIST 元素名 属性名 属性类型 #REQUIRED>
DTD示例:
<!ATTLIST person number CDATA #REQUIRED>
XML示例:
<person number="6788"/>
#IMPLIED:元素的实例中可以忽略该属性(NULL)。
语法
<!ATTLIST 元素名 属性名 属性类型 #IMPLIED>
DTD示例:
<!ATTLIST contact fax CDATA #IMPLIED>
XML示例:
<contact fax="888-228833"/>
没有这个属性也是对的。
#FIXED value:元素实例中该属性的值必须为指定的固定值。
语法:
<!ATTLIST 元素名 属性名 属性类型 #FIXED "value">
DTD示例:
<!ATTLIST sender company CDATA #FIXED "Microsoft">
XML示例:
<sender company="Microsoft"/>
Default value:为属性提供一个默认的值。
语法:
<!ATTLIST 元素名 属性名 属性类型 "value">
DTD示例:
<!ATTLIST hello paymenttype CDATA "check">
XML示例:
<hello paymenttype="check"/>
定义实体
一般
语法:
<!ENTITY 实体名 "实体值">
DTD示例
<!ENTITY writer "Donald Duck"> <!ENTITY copyright "Copyright W3Schools">
XML示例:
<author>&writer;©right;</author>
外部实体:
语法
<!ENTITY 实体名 SYSTEM "URI/URL">
DTD示例:
<!ENTITY writer SYSTEM "http://www.baidu.com/index.php?tn=coralqq"> <!ENTITY copyright SYSTEM "http://www.baidu.com/index.php?tn=coralqq">
XML示例:
<author>&writer;©right;</author>
与上面的区别就是加上了SYSTEM关键字。
这样就不是使用网址的字符串来代替,而是用网址的文档本身内容。
实体类型
前面所讲的都是普通实体,分为内部实体和外部实体。
所谓参数实体,该实体实际上不是在具体实例化文档中使用,而是在DTD文档内部被使用。
我们可以定义一个实体,然后在DTD内部来引用它。
如下:
<!ENTITY %地址 "街道,城市,邮编,国家"> <!ELEMENT 联系人 (人名,电话,%地址;)>
总结如下:
普通实体:DTD中定义,XML中使用,使用格式: &名;
参数实体:DTD中定义,定义的时候要用%,DTD中使用,使用格式: %名;
普通实体和参数实体都分为内部实体和外部实体两种,外部实体定义需要加上SYSTEM关键字,其内容是URL所指向的外部文件实际的内容。
如果不加SYSTEM关键字,则为内部实体,表示实体指代内容为字符串。