转载出处:http://www.zhuoda.org/irini/43776.html
1. DTD简介
DTD(Document Type Definition)定义了XML文档的合法构造块,他用一系列合法的元素定义文档结构
DTD可以在XML文档的内部声明,也可以外部引用
为什么要用DTD呢?
使用DTD,我们每个XML文件都可以有自己的格式描述
使用DTD,独立的组织间可以用公用的DTD交换数据
在你的应用中可以用DTD检验你从外界得到的数据是否有效
内部DOCTYPE 声明
语法: <!DOCTYPE root-element [element-declarations]>
看个例子:
<?xml version="1.0"?>
<!DOCTYPE note [
<!ELEMENT note (to,from,heading,body)>
<!ELEMENT to (#PCDATA)>
<!ELEMENT from (#PCDATA)>
<!ELEMENT heading (#PCDATA)>
<!ELEMENT body (#PCDATA)>
]>
<note>
<to>Tove</to>
<from>Jani</from>
<heading>Reminder</heading>
<body>Don't forget me this weekend</body>
</note>
!DOCTYPE note 定义了这是一个note类型的文档
!ELEMENT note 定义note 有4个子元素 to,body
!ELEMENT to 定义to 这个元素是 #PCDATA 类型的
其他类似
外部DOCTYPE 声明
语法: <!DOCTYPE root-element SYSTEM "filename">
例子:
<?xml version="1.0"?>
<!DOCTYPE note SYSTEM "note.dtd">
<note>
<to>Tove</to>
<from>Jani</from>
<heading>Reminder</heading>
<body>Don't forget me this weekend!</body>
</note>
note.dtd:
<!ELEMENT note (to,body)>
<!ELEMENT to (#PCDATA)>
<!ELEMENT from (#PCDATA)>
<!ELEMENT heading (#PCDATA)>
<!ELEMENT body (#PCDATA)>
我们已经定义了DTD,也按照定义写了XML文档,那如何验证呢?下面就用javascript验证一下
先写个错误的XML,然后用javascript检验
note_dtd_error.xml:
<?xml version="1.0"?>
<!DOCTYPE note [
<!ELEMENT note (to,body)>
<!ELEMENT to (#PCDATA)>
<!ELEMENT from (#PCDATA)>
<!ELEMENT heading (#PCDATA)>
<!ELEMENT body (#PCDATA)>
]>
<note>
<to>Tove</to>
<fromm>Jani</fromm>
<heading>Reminder</heading>
<body>Don't forget me this weekend!</body>
</note>
validate.html:
<html>
<body>
<h3>
This demonstrates a parser error:
</h3>
<script type="text/javascript">
var xmlDoc = new ActiveXObject("Microsoft.XMLDOM")
xmlDoc.async="false"
xmlDoc.validateOnParse="true"
xmlDoc.load("note_dtd_error.xml")
document.write("<br />Error Code: ")
document.write(xmlDoc.parseError.errorCode)
document.write("<br />Error Reason: ")
document.write(xmlDoc.parseError.reason)
document.write("<br />Error Line: ")
document.write(xmlDoc.parseError.line)
</script>
</body>
</html>
运行validate.html 可以看到以下信息:
This demonstrates a parser error:
Error Code: -1072898028
Error Reason: 根据 DTD/Schema,元素内容无效。预期: from。
Error Line: 12
DTD的概貌和如何验证已经看过了,接下来看一下DTD的具体语法
2. DTD-XML 构造块
在DTD看来,XML文档都是由以下简单的改造块构成的:
Elements
Attributes
Entities
PCDATA
CDATA
Elements
Elements是主要的构造块,可以包含文本,其他元素,或者为空,如
<message>some message in between</message>
Attributes
Attributes为Elements提供额外信息,他总是在Elements的起始标签中,总是以 name/value对 出现
Entities
Entities是用语定义通用文本的变量,Entities在XML文档被解析时被展开,下面的是XML预定义的实体:
< <
> >
& &
" "
' '
PCDATA
PCDATA是字符数据,是会被解析的文本,文本中的tags会被当作标记处理,entities会被展开
CDATA
CDATA也是字符数据,但他是不会被解析的文本,文本中的tags不会被当作标记处理,entities也不会被展开
3. Elements
(1)声明一个Element,语法:
<!ELEMENT element-name category>
or
<!ELEMENT element-name (element-content)>
(2)Empty elements,用关键字 EMPTY 来声明
<!ELEMENT element-name EMPTY>
example:
<!ELEMENT br EMPTY>
XML example:
<br />
(3)Elements 只包含字符数据时,用 #PCDATA 来声明
<!ELEMENT element-name (#PCDATA)>
example:
<!ELEMENT from (#PCDATA)>
(4)Elements with any contents,用 ANY 声明时,元素可包含任何可以被解析的数据
<!ELEMENT element-name ANY>
example:
<!ELEMENT note ANY>
(5)Elements with children (sequences)
<!ELEMENT element-name
(child-element-name)>
or
<!ELEMENT element-name
(child-element-name,child-element-name,.....)>
example:
<!ELEMENT note (to,body)>
子元素出现的顺序必须和声明时的一致,子元素也可以有子元素
(6) 声明相同元素只出现一次
<!ELEMENT element-name (child-name)>
example:
<!ELEMENT note (message)>
说明 message 在 note 中只能出现一次
(7) 声明相同元素至少出现一次
<!ELEMENT element-name (child-name+)>
example:
<!ELEMENT note (message+)>
"+"说明 message 在 note 中至少出现一次
(7) 声明相同元素出现0次或多次
<!ELEMENT element-name (child-name*)>
example:
<!ELEMENT note (message*)>
"*"说明 message 在 note 中的出现是随意的
(8) 声明相同元素出现0次或一次
<!ELEMENT element-name (child-name?)>
example:
<!ELEMENT note (message?)>
"?"说明 message 在 note 中可不出现,或者出现一次
(9) 声明 either/or 内容
example:
<!ELEMENT note (to,header,(message|body))>
note 必须包含一个to,一个from,一个header,和message body其中之一
(10) 声明混合内容
example:
<!ELEMENT note (#PCDATA|to|from|header|message)*>
note 可以包含 可被解析的字符,to,message,并且可以出现任意次
4. Attributes
(1) 声明Attributes,语法:
<!ATTLIST element-name attribute-name
attribute-type default-value>
example:
DTD example:
<!ATTLIST payment type CDATA "check">
XML example:
<payment type="check" />
attribute-type 有下列值:
CDATA 字符数据
(en1|en2|..) 值必须是枚举列表中的一个
ID unique id
IDREF 其他元素的id
IDREFS 其他id 列表
NMTOKEN 一个有效的XML名字
NMTOKENS 有效的XML名列表
ENTITY 一个实体
ENTITIES 一个实体列表
NOTATION 一个符号名
xml: 一个预定义的XML值
default-value 有下列值:
value 默认值
#required 这个属性必须出现
#IMPLIED 这个属性不是必须的
#FIXED value 这个属性的只是固定的
(2) 指定一个默认值属性
DTD:
<!ELEMENT square EMPTY>
<!ATTLIST square width CDATA "0">
Valid XML:
<square width="100" />
square被定义为一个空元素,他有一个CDATA类型的属性 width,如果width没被指定值,那他就是0
(3) #IMPLIED
语法:
<!ATTLIST element-name attribute-name
attribute-type #IMPLIED>
example:
DTD:
<!ATTLIST contact fax CDATA #IMPLIED>
Valid XML:
<contact fax="555-667788" />
Valid XML:
<contact />
(4) #required
语法:
<!ATTLIST element-name attribute_name
attribute-type #required>
Example
DTD:
<!ATTLIST person number CDATA #required>
Valid XML:
<person number="5677" />
Invalid XML:
<person />
(5) #FIXED
语法:
<!ATTLIST element-name attribute-name
attribute-type #FIXED "value">
Example
DTD:
<!ATTLIST sender company CDATA #FIXED "Microsoft">
Valid XML:
<sender company="Microsoft" /
Invalid XML:
<sender company="W3Schools" />
(6) Enumerated attribute values
<!ATTLIST element-name
attribute-name (en1|en2|..) default-value>
DTD example:
<!ATTLIST payment type (check|cash) "cash">
XML example:
<payment type="check" />
or
<payment type="cash" />
5. Entities
Entities 是用来为普通文本定义捷径
有两种声明方式:
(1) 内部声明
Syntax:
<!ENTITY entity-name "entity-value">
DTD Example:
<!ENTITY writer "Donald Duck.">
<!ENTITY copyright "Copyright W3Schools.">
XML example:
<author>&writer;©right;</author>
(2) 外部声明
Syntax:
<!ENTITY entity-name SYSTEM "URI/URL">
DTD Example:
<!ENTITY writer
SYSTEM "http://www.w3schools.com/dtd/entities.dtd">
!ENTITY copyright
SYSTEM "http://www.w3schools.com/dtd/entities.dtd"> XML example: <author>&writer;©right;</author>