-- 作者:admin
-- 发布时间:2008/2/20 15:20:16
-- [推荐]XML学习资料之二——DTD
1 DTD的声明和引用 合法的XML文档必须符合DTD指定的约束条件,在XML文档的数据结构定义部分用于指定文档所使用的DTD,DTD有内部和外部之分。
1、1 内部DTD 处于XML声明和文档主体之间,以“<!DOCTYPE”开始,后跟根元素名称,处于“[”和“]”之间的内容为元素定义,位于“<!ELEMENT”后。所有内容无需换行,不过换行更易于阅读 <?xml version="1.0" encoding="gb2312" standal?> <!DOCTYPE students [ <!ELEMENT birthday (#PCDATA)> <!ELEMENT course (#PCDATA)> <!ELEMENT grade (#PCDATA)> <!ELEMENT height (#PCDATA)> <!ELEMENT name (#PCDATA)> <!ELEMENT number (#PCDATA)> <!ELEMENT sex (#PCDATA)> <!ELEMENT sgrade (number, course, grade)> <!ELEMENT stu (number, name, sex, birthday, height, sgrade+)> <!ELEMENT students (stu)> ]> <!--This is a comment!--> <students> <stu> <number>000001</number> <name>黎明</name> <sex>1</sex> <birthday>1976-11-23</birthday> <height>1.8</height> <sgrade> <number>000001</number> <course>A03</course> <grade>56</grade> </sgrade> <sgrade> <number>000001</number> <course>B01</course> <grade>78</grade> </sgrade> </stu> </students>
1、2 外部DTD 将DTD内容单独保存为文件,便于共享,如建立DTD为stu.dtd: <?xml version="1.0" encoding="UTF-8"?> <!ELEMENT birthday (#PCDATA)> <!ELEMENT course (#PCDATA)> <!ELEMENT grade (#PCDATA)> <!ELEMENT height (#PCDATA)> <!ELEMENT name (#PCDATA)> <!ELEMENT number (#PCDATA)> <!ELEMENT sex (#PCDATA)> <!ELEMENT sgrade (number, course, grade)> <!ELEMENT stu (number, name, sex, birthday, height, sgrade+)> <!ELEMENT students (stu)> 相应的XML文件为: <?xml version="1.0" encoding="gb2312" standal?> <!DOCTYPE students SYSTEM "stu.dtd"> <!--This is a comment!--> <students> <stu> <number>000001</number> <name>黎明</name> <sex>1</sex> <birthday>1976-11-23</birthday> <height>1.8</height> <sgrade> <number>000001</number> <course>A03</course> <grade>56</grade> </sgrade> <sgrade> <number>000001</number> <course>B01</course> <grade>78</grade> </sgrade> </stu> </students>
说明: 1)SYSTEM为关键字,是指该外部DTD文件是私有的,即我们自己创建的,没有公开发行,只是个人或在公司内部或者几个合作单位之间使用;而PUBLIC关键字是指该外部DTD是公用的,经过了公开讨论,用PUBLIC的DTD都有一个逻辑名称——DTD-name,我们必须在调用时指明这个逻辑名称 2)<!DOCTYPE students SYSTEM "stu.dtd">为引用DTD文档的声明,一个XML文档只能有一个DTD文档声明
1、3 内外DTD的结合 较为通用的部分可以放在外部DTD中,内部DTD内容主要与特定主题有关 修改DTD,添加otherInfo为: <?xml version="1.0" encoding="UTF-8"?> <!ELEMENT birthday (#PCDATA)> <!ELEMENT course (#PCDATA)> <!ELEMENT grade (#PCDATA)> <!ELEMENT height (#PCDATA)> <!ELEMENT name (#PCDATA)> <!ELEMENT number (#PCDATA)> <!ELEMENT sex (#PCDATA)> <!ELEMENT sgrade (number, course, grade)> <!ELEMENT stu (number, name, sex, birthday, height, sgrade+,otherInfo)> <!ELEMENT students (stu)>
修改XML文件为: <?xml version="1.0" encoding="gb2312" standal?> <!DOCTYPE students SYSTEM "stu.dtd"[ <!ELEMENT otherInfo (address)> <!ELEMENT address (#PCDATA)> ]>
<!--This is a comment!--> <students> <stu> <number>000001</number> <name>黎明</name> <sex>1</sex> <birthday>1976-11-23</birthday> <height>1.8</height> <sgrade> <number>000001</number> <course>A03</course> <grade>56</grade> </sgrade> <sgrade> <number>000001</number> <course>B01</course> <grade>78</grade> </sgrade> <otherInfo> <address>Nanjing</address> </otherInfo> </stu> </students>
注意:外部DTD定义过的元素不可在内部DTD中再次定义
2 DTD元素的使用 2、1 特殊控制标签的使用 主要用于修饰相关元素的出现次数等信息,如: ?——0或者1次 *——大于等于0次 +——大于等于1次(至少出现1次)
2、2 数据类型 2、2、1 #PCDATA 含义为包含可以解析的字符,不能含有自己的子元素
2、2、2 EMPTY 含义为空元素,如: <!ELEMENT address EMPTY> 此时必须使用为:<address></address>
2、2、3 ANY 含义为自由格式,可以插入文字,而且可以出现子元素,次数与顺序皆不限。尽量限制使用该类型。使用方法如: <!ELEMENT address ANY> 注意:即便是自由格式,但在元素中也不能包含未被定义的子元素
2、2、4 选择类型 使用分隔符“|”表示,表示多者只能选择一个,如: <!ELEMENT address (city | country)> <!ELEMENT city (#PCDATA)> <!ELEMENT country (#PCDATA)>
相应的XML元素为: <address> <city>nanjing</city> </address>
而且还可以综合使用控制标签,如: <!ELEMENT address (city+ | country)> <!ELEMENT city (#PCDATA)> <!ELEMENT country (#PCDATA)>
2、2、5 混合类型 既可以包含子元素,也可以包含文本文字,如: <!ELEMENT address (#PCDATA | city)*> <!ELEMENT city (#PCDATA)>
相应的XML元素为: <address> Address Information <city>nanjing</city> </address>
注意:此时必须在DTD定义元素后加上“*”,否则无法通过检查
2、3 实体(ENTITY)声明和使用 实体类似于常数,可以由一个文件、数据库记录或者含有数据的项目组成,通过实体名称来得到它的引用。 有些实体是内定的,如“>”等,也可以自定义新的实体
2、3、1 内部实体 定义方法为“<!ENTITY”,如DTD为: <!ENTITY myname "lishuqing"> <!ENTITY myemail "&myname;@mail.com"> <!ENTITY otherElement "<city>nanjing</city>"> <!ELEMENT address (#PCDATA | city)*> <!ELEMENT city (#PCDATA)>
相应的XML元素为: <address> &myname;&myemail; &otherElement; </address>
完整的文件为: <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE address[ <!ENTITY myname "lishuqing"> <!ENTITY myemail "&myname;@mail.com"> <!ENTITY otherElement "<city>nanjing</city>"> <!ELEMENT address (#PCDATA | city)*> <!ELEMENT city (#PCDATA)> ]> <address> &myname;&myemail; &otherElement; </address>
显示结果为: <address> lishuqing lishuqing @mail.com <city>nanjing</city> </address>
注意: 1)替换文本要放在双引号中,其中可以放入空格,“<”和XML标签等符号。 2)实体的引用可以放在XML文档和DTD文档中 3)实体中可以引用其他实体,但是不要循环引用 <!ENTITY myname "lishuqing"> <!ENTITY otherElement "<city>&myname;</city>"> 4)可以先使用再声明 5)只能在定义的文件中使用,不能在外部DTD中定义,再到XML文档中使用
2、3、2 外部实体 实体中的数据从文档外部获取,如从text.txt文档获取实体数据: <!ENTITY contents SYSTEM "text.txt"> <!ENTITY otherElement "<city>&contents;</city>">
注意:此时应该将XML文件的standalone属性设置为no
2、3、3 参数实体 在外部DTD文档中,对于反复使用的元素成员,可以考虑使用参数实体来替换,替换的内容要比一般实体更为复杂,甚至包含数据类型的定义语句
如DTD文档为: <?xml version="1.0" encoding="UTF-8"?> <!ELEMENT otherInfo (address)> <!ENTITY % pcd "(#PCDATA)"> <!ENTITY % ncg "(number, course, grade)"> <!ELEMENT address (#PCDATA | city)*> <!ELEMENT city %pcd;> <!ELEMENT birthday (#PCDATA)> <!ELEMENT course (#PCDATA)> <!ELEMENT grade (#PCDATA)> <!ELEMENT height (#PCDATA)> <!ELEMENT name (#PCDATA)> <!ELEMENT number (#PCDATA)> <!ELEMENT sex (#PCDATA)> <!ELEMENT sgrade (number, course, grade)> <!ELEMENT stu (number, name, sex, birthday, height, sgrade+,otherInfo)> <!ELEMENT students (stu)>
相应的XML文档为: <?xml version="1.0" encoding="gb2312" standal?> <!DOCTYPE students SYSTEM "stu.dtd">
<!--This is a comment!--> <students> <stu> <number>000001</number> <name>黎明</name> <sex>1</sex> <birthday>1976-11-23</birthday> <height>1.8</height> <sgrade> <number>000001</number> <course>A03</course> <grade>56</grade> </sgrade> <sgrade> <number>000001</number> <course>B01</course> <grade>78</grade> </sgrade> <otherInfo> <address> <city>Nanjing</city> </address> </otherInfo> </stu> </students>
说明: 1)参数实体只能在外部DTD中使用,不能在内部DTD中使用 2)参数实体的引用只能在DTD中出现,不能在XML文档中出现 3)必须先声明参数实体,才能使用,与普通实体不同 4)使用%替代&来表示 5)不是任何地方都可以使用参数实体,如:<!ELEMENT address (#PCDATA | city)*>中只能直接使用#PCDATA
2、4 属性(Attribute)声明和使用 使用“<!ATTLIST”来定义属性,如: <?xml version="1.0" encoding="gb2312" standal?> <!DOCTYPE students [ <!ELEMENT birthday (#PCDATA)> <!ELEMENT course (#PCDATA)> <!ELEMENT avggrade (#PCDATA)> <!ELEMENT height (#PCDATA)> <!ELEMENT name (#PCDATA)> <!ELEMENT number (#PCDATA)> <!ELEMENT sex (#PCDATA)> <!ELEMENT sgrade (avggrade)> <!ATTLIST sgrade number CDATA #REQUIRED sex (male | female) "male" age CDATA #IMPLIED course CDATA #FIXED "ALL" > <!ELEMENT stu (number, name, sex, birthday, height, sgrade+)> <!ELEMENT students (stu)> ]> <!--This is a comment!--> <students> <stu> <number>000001</number> <name>黎明</name> <sex>1</sex> <birthday>1976-11-23</birthday> <height>1.8</height> <sgrade number="000001" age="30" course="ALL" sex="male"> <avggrade>67</avggrade> </sgrade> </stu> </students>
说明: 1)上述属性定义使用大量属性的数据类型,具体解释如下: cdata 属性值仅仅是一般的文字,不包含“<”和“"”的任意字符。 enumerated 列出该属性的枚举取值列表,一次只能有一个属性值能够赋予属性。 nmtoken 表示属性值只能由字母、数字、下划线、.、:、-这些符号组成,不能有空格。 nmtokens 表示属性值能够由多个nmtoken组成,每个nmtoken之间用空格隔开。 id 该属性在xml文件中是唯一的。 idref 表示该属性值是参考了另一个id属性。 idrefs 表示该属性值是参考了多个id属性,这些id属性的值用空格隔开。 entity 表示该属性的设定值是一个外部的entity,如一个图片文件。 entities 该属性值包含了多个外部entity,不同的entity之间用空格隔开。 notation 属性值是在dtd中声明过的notation(声明用什么应用软件解读某些二进制文件,如图片)。
2)属性的内定值 #REQUIRED 必须提供属性 #IMPLIED 可以忽略属性 #FIXED 具有固定的属性值(id和idref等类型不能为此内定值)
[此贴子已经被作者于2010-12-11 19:53:41编辑过]
|