DTD是什么
DTD-Document Type Definition,中文翻译即文档类型定义,可定义合法的XML文档构建模块。它使用一系列合法的元素来定义文档的结构。
如何使用DTD
- 内部声明DTD
DTD可以直接包含于XML源文件中,使用方法如下> <!DOCTYPE 根元素 [元素声明]>
一个简单的例子如下
<!DOCTYPE note [
<!ELEMENT note (to,from,heading,body)>
<!ELEMENT to (#PCDATA)>
<!ELEMENT from (#PCDATA)>
<!ELEMENT heading (#PCDATA)>
<!ELEMENT body (#PCDATA)>
]>
<note>
<to>George</to>
<from>John</from>
<heading>Reminder</heading>
<body>Don't forget the meeting!</body>
</note>
- 外部声明DTD
也可以将DTD单独的写进一个外部文件中,只需要在XML里面导入即可。使用方法如下:
> <!DOCTYPE 根元素 SYSTEM "文件名">
我们假设存在DTD文件名为 note.dtd ,内容如下:
<!ELEMENT note (to,from,heading,body)>
<!ELEMENT to (#PCDATA)>
<!ELEMENT from (#PCDATA)>
<!ELEMENT heading (#PCDATA)>
<!ELEMENT body (#PCDATA)>
则上面的包含DTD的XML可以写成:
<!DOCTYPE note SYSTEM "note.dtd">
<note>
<to>George</to>
<from>John</from>
<heading>Reminder</heading>
<body>Don't forget the meeting!</body>
</note>
DTD的组成
所有的 XML 文档(以及 HTML 文档)均由以下简单的构建模块构成:
- 元素
- 属性
- 实体
- PCDATA
- CDATA
下面是每个构建模块的详细描述。
元素
元素可包含文本、其他元素或者是空的。元素声明使用如下的语法:
<!ELEMENT 元素名 类别>
或者是
<!ELEMENT 元素名 (元素内容)>
空元素
如果一个元素不包含任何内容时,可以通过使用EMPTY来进行声明:
<!ELEMENT 元素名称 EMPTY>
具体例子如:
<!ELEMENT br EMPTY>
对应的XML即为:
<br />
只有PCDATA的元素
<!ELEMENT 元素名称 (#PCDATA)>
带有任何内容的元素
通过类别关键词 ANY 声明的元素,可包含任何可解析数据的组合:
<!ELEMENT 元素名称 ANY>
带有子元素的元素
带有一个或多个子元素的元素通过圆括号中的子元素名进行声明:
<!ELEMENT 元素名称 (子元素名称 1,子元素名称 2,.....)>
如上面的例子:
<!ELEMENT note (to,from,heading,body)>
当子元素按照由逗号分隔开的序列进行声明时,这些子元素必须按照相同的顺序出现在文档中。在一个完整的声明中,子元素也必须被声明,同时子元素也可拥有子元素。"note" 元素的完整声明是:
<!ELEMENT note (to,from,heading,body)>
<!ELEMENT to (#PCDATA)>
<!ELEMENT from (#PCDATA)>
<!ELEMENT heading (#PCDATA)>
<!ELEMENT body (#PCDATA)>
声明只出现一次的元素
<!ELEMENT 元素名称 (子元素名称)>
例子:
<!ELEMENT note (message)>
上面的例子表明了 message子元素必须出现一次,而且只能在 note 元素中出现一次
声明至少出现一次的元素
<!ELEMENT 元素名称 (子元素名称+)>
例子:
<!ELEMENT note (message)>
上面的例子中的加号声明了:message 子元素必须在 "note" 元素内出现至少一次。
声明出现零次或多次的元素
<!ELEMENT 元素名称 (子元素名称*)>
例子:
<!ELEMENT note (message)*>
上面的例子中的星号声明了:子元素 message 可在 "note" 元素内出现零次或多次。
声明出现零次或一次的元素
<!ELEMENT 元素名称 (子元素名称?)>
例子:
<!ELEMENT note (message?)>
上面的例子中的问号声明了:子元素 message 可在 "note" 元素内出现零次或一次。
声明 或者出现的元素
<!ELEMENT note (message|body)>
上面的例子标明了要么出现message,要么出现body。
属性
属性可提供有关元素的额外信息。属性总是被置于某元素的开始标签中。属性总是以名称/值的形式成对出现的。
属性声明使用下列语法:
<!ATTLIST 元素名称 属性名称 属性类型 默认值>
DTD 实例:
<!ATTLIST payment type CDATA "check">
XML 实例:
<payment type="check" />
以下是属性类型的选项:
类型 描述
CDATA 值为字符数据 (character data)
(en1|en2|..) 此值是枚举列表中的一个值
ID 值为唯一的 id
IDREF 值为另外一个元素的 id
IDREFS 值为其他 id 的列表
NMTOKEN 值为合法的 XML 名称
NMTOKENS 值为合法的 XML 名称的列表
ENTITY 值是一个实体
ENTITIES 值是一个实体列表
NOTATION 此值是符号的名称
xml: 值是一个预定义的 XML 值
默认值参数可使用下列值:
值 属性的默认值
#REQUIRED 属性值是必需的
#IMPLIED 属性不是必需的
#FIXED value 属性值是固定的
实体
实体是用来定义普通文本的变量。实体引用是对实体的引用。大多数同学都了解这个 HTML 实体引用:" "。这个“无折行空格”实体在 HTML 中被用于在某个文档中插入一个额外的空格。当文档被 XML 解析器解析时,实体就会被展开。
PCDATA
PCDATA 的意思是被解析的字符数据(parsed character data)。可把字符数据想象为 XML 元素的开始标签与结束标签之间的文本。PCDATA 是会被解析器解析的文本。这些文本将被解析器检查实体以及标记。文本中的标签会被当作标记来处理,而实体会被展开。不过,被解析的字符数据不应当包含任何 &、< 或者 > 字符;需要使用 &、< 以及 > 实体来分别替换它们。
CDATA
CDATA 的意思是字符数据(character data)。CDATA 是不会被解析器解析的文本。在这些文本中的标签不会被当作标记来对待,其中的实体也不会被展开。
具体使用例子
如下是一个XML文件,我们考虑找出它的DTD。
<Course_Catalog>
<Department Code="CS" Chair="JW">
<Title>Computer Science</Title>
<Course Number="CS106A" Instructors="JC ER MS" Enrollment="1070">
<Title>Programming Methodology</Title>
<Description>Introduction to the engineering of computer applications emphasizing modern software engineering principles.</Description>
</Course>
<Course Number="CS106B" Prerequisites="CS106A" Instructors="JC ER" Enrollment="620">
<Title>Programming Abstractions</Title>
<Description>Abstraction and its relation to programming.</Description>
</Course>
<Course Number="CS107" Prerequisites="CS106B" Instructors="JZ" Enrollment="500">
<Title>Computer Organization and Systems</Title>
<Description>Introduction to the fundamental concepts of computer systems.</Description>
</Course>
<Course Number="CS109" Prerequisites="CS106B" Instructors="MS" Enrollment="280">
<Title>Introduction to Probability for Computer Scientists</Title>
</Course>
<Course Number="CS124" Prerequisites="CS107 CS109" Instructors="DJ" Enrollment="60">
<Title>From Languages to Information</Title>
<Description>Natural language processing. Cross-listed as <Courseref Number="LING180"/>.</Description>
</Course>
<Course Number="CS143" Prerequisites="CS107" Instructors="AA" Enrollment="90">
<Title>Compilers</Title>
<Description>Principles and practices for design and implementation of compilers and interpreters.</Description>
</Course>
<Course Number="CS145" Prerequisites="CS107" Instructors="JW" Enrollment="130">
<Title>Introduction to Databases</Title>
<Description>Database design and use of database management systems for applications.</Description>
</Course>
<Course Number="CS221" Prerequisites="CS107" Instructors="AN ST" Enrollment="180">
<Title>Artificial Intelligence: Principles and Techniques</Title>
</Course>
<Course Number="CS228" Instructors="DK" Enrollment="110">
<Title>Structured Probabilistic Models: Principles and Techniques</Title>
<Description>Using probabilistic modeling languages to represent complex domains.</Description>
</Course>
<Course Number="CS229" Instructors="AN" Enrollment="320">
<Title>Machine Learning</Title>
<Description>A broad introduction to machine learning and statistical pattern recognition.</Description>
</Course>
<Professor InstrID="AA">
<First_Name>Alex</First_Name>
<Middle_Initial>S.</Middle_Initial>
<Last_Name>Aiken</Last_Name>
</Professor>
<Lecturer InstrID="JC">
<First_Name>Jerry</First_Name>
<Middle_Initial>R.</Middle_Initial>
<Last_Name>Cain</Last_Name>
</Lecturer>
<Professor InstrID="DK">
<First_Name>Daphne</First_Name>
<Last_Name>Koller</Last_Name>
</Professor>
<Professor InstrID="AN">
<First_Name>Andrew</First_Name>
<Last_Name>Ng</Last_Name>
</Professor>
<Professor InstrID="ER">
<First_Name>Eric</First_Name>
<Last_Name>Roberts</Last_Name>
</Professor>
<Professor InstrID="MS">
<First_Name>Mehran</First_Name>
<Last_Name>Sahami</Last_Name>
</Professor>
<Professor InstrID="ST">
<First_Name>Sebastian</First_Name>
<Last_Name>Thrun</Last_Name>
</Professor>
<Professor InstrID="JW">
<First_Name>Jennifer</First_Name>
<Last_Name>Widom</Last_Name>
</Professor>
<Lecturer InstrID="JZ">
<First_Name>Julie</First_Name>
<Last_Name>Zelenski</Last_Name>
</Lecturer>
</Department>
<Department Code="EE" Chair="MH">
<Title>Electrical Engineering</Title>
<Course Number="EE108A" Instructors="SM">
<Title>Digital Systems I</Title>
<Description>Digital circuit, logic, and system design.</Description>
</Course>
<Course Number="EE108B" Prerequisites="EE108A CS106B" Instructors="WD OO">
<Title>Digital Systems II</Title>
<Description>The design of processor-based digital systems.</Description>
</Course>
<Professor InstrID="WD">
<First_Name>William</First_Name>
<Middle_Initial>J.</Middle_Initial>
<Last_Name>Dally</Last_Name>
</Professor>
<Professor InstrID="MH">
<First_Name>Mark</First_Name>
<Middle_Initial>A.</Middle_Initial>
<Last_Name>Horowitz</Last_Name>
</Professor>
<Professor InstrID="SM">
<First_Name>Subhasish</First_Name>
<Last_Name>Mitra</Last_Name>
</Professor>
<Professor InstrID="OO">
<First_Name>Oyekunle</First_Name>
<Last_Name>Olukotun</Last_Name>
</Professor>
</Department>
<Department Code="LING" Chair="BL">
<Title>Linguistics</Title>
<Course Number="LING180" Prerequisites="CS107 CS109" Instructors="DJ" Enrollment="60">
<Title>From Languages to Information</Title>
<Description>Natural language processing. Cross-listed as <Courseref Number="CS124"/>.</Description>
</Course>
<Professor InstrID="DJ">
<First_Name>Dan</First_Name>
<Last_Name>Jurafsky</Last_Name>
</Professor>
<Professor InstrID="BL">
<First_Name>Beth</First_Name>
<Last_Name>Levin</Last_Name>
</Professor>
</Department>
</Course_Catalog>
对应的DTD如下:
<!ELEMENT Course_Catalog (Department)*>
<!ELEMENT Department (Title,Course+,(Professor|Lecturer)*)>
<!ELEMENT Title (#PCDATA)>
<!ELEMENT Course (Title,Description?)>
<!ELEMENT Description (#PCDATA | Courseref)*>
<!ELEMENT Courseref EMPTY>
<!ATTLIST Courseref Number IDREF #REQUIRED>
<!ELEMENT Professor (First_Name,Middle_Initial?,Last_Name)>
<!ELEMENT Lecturer (First_Name,Middle_Initial?,Last_Name)>
<!ELEMENT First_Name (#PCDATA)>
<!ELEMENT Middle_Initial (#PCDATA)>
<!ELEMENT Last_Name (#PCDATA)>
<!ATTLIST Department Code CDATA #REQUIRED Chair IDREF #REQUIRED>
<!ATTLIST Course Number ID #REQUIRED Prerequisites IDREFS #IMPLIED Instructors IDREFS #REQUIRED
Enrollment CDATA #IMPLIED>
<!ATTLIST Professor InstrID ID #REQUIRED>
<!ATTLIST Lecturer InstrID ID #REQUIRED>