文档类型定义(Document Type Definition)
可定义合法的XML文档构建模块
它使用一系列合法的元素来定义文档的结构。
DTD 可被成行地声明于 XML 文档中,也可作为一个外部引用。
内部的 DOCTYPE 声明
假如 DTD 被包含在您的 XML 源文件中,它应当通过下面的语法包装在一个 DOCTYPE 声明中:
<!DOCTYPE 根元素 [元素声明]>
带有 DTD 的 XML 文档实例(请在 IE5 以及更高的版本打开,并选择查看源代码):
<?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>George</to> <from>John</from> <heading>Reminder</heading> <body>Don't forget the meeting!</body> </note>
外部文档声明
假如 DTD 位于 XML 源文件的外部,那么它应通过下面的语法被封装在一个 DOCTYPE 定义中:
<!DOCTYPE 根元素 SYSTEM "文件名">
这个 XML 文档和上面的 XML 文档相同,但是拥有一个外部的 DTD:
<?xml version="1.0"?> <!DOCTYPE note SYSTEM "note.dtd"> <note> <to>George</to> <from>John</from> <heading>Reminder</heading> <body>Don't forget the meeting!</body> </note>
这是包含 DTD 的 “note.dtd” 文件:
<!ELEMENT note (to,from,heading,body)> <!ELEMENT to (#PCDATA)> <!ELEMENT from (#PCDATA)> <!ELEMENT heading (#PCDATA)> <!ELEMENT body (#PCDATA)>
为什么使用 DTD
通过 DTD,每一个 XML 文件均可携带一个有关其自身格式的描述。
通过 DTD,独立的团体可一致地使用某个标准的 DTD 来交换数据。
应用程序可使用某个标准的 DTD 来验证从外部接收到的数据。
可以使用 DTD 验证自身的数据。声明元素
在 DTD 中,XML 元素通过元素声明来进行声明。元素声明使用下面的语法:
<!ELEMENT 元素名称 类别>
或者
<!ELEMENT 元素名称 (元素内容)>
空元素
空元素通过类别关键词EMPTY进行声明:<!ELEMENT 元素名称 EMPTY>
例子:
<!ELEMENT br EMPTY>
XML例子:
<br />
只有 PCDATA 的元素
只有 PCDATA 的元素通过圆括号中的 #PCDATA 进行声明:<!ELEMENT 元素名称 (#PCDATA)>
例子:
<!ELEMENT from (#PCDATA)>
带有任何内容的元素
通过类别关键词 ANY 声明的元素,可包含任何可解析数据的组合:<!ELEMENT 元素名称 ANY>
例子:
带有子元素(序列)的元素
带有一个或多个子元素的元素通过圆括号中的子元素名进行声明:<!ELEMENT 元素名称 (子元素名称 1)>
或者
<!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 (to,from,header,(message|body))>
上面的例子声明了:”note” 元素必须包含 “to” 元素、”from” 元素、”header” 元素,以及非 “message” 元素既 “body” 元素。
声明混合型的内容
例子:<!ELEMENT note (#PCDATA|to|from|header|message)*>
上面的例子声明了:”note” 元素可包含出现零次或多次的 PCDATA、”to”、”from”、”header” 或者 “message”。
声明属性
在 DTD 中,属性通过 ATTLIST 声明来进行声明。
属性声明使用下列语法:
<!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属性值是固定的
规定一个默认的属性值
DTD:<!ELEMENT square EMPTY> <!ATTLIST square width CDATA "0">
合法的 XML:
<square width="100" />
在上面的例子中,”square” 被定义为带有 CDATA 类型的 “width” 属性的空元素。如果宽度没有被设定,其默认值为0 。
#IMPLIED
语法<!ATTLIST 元素名称 属性名称 属性类型 #IMPLIED>
例子
DTD:<!ATTLIST contact fax CDATA #IMPLIED>
合法的 XML:
<contact fax="555-667788" />
合法的 XML:
<contact />
假如您不希望强制作者包含属性,并且您没有默认值选项的话,请使用关键词 #IMPLIED。
#REQUIRED
语法<!ATTLIST 元素名称 属性名称 属性类型 #REQUIRED>
例子
DTD:<!ATTLIST person number CDATA #REQUIRED>
合法的 XML:
<person number="5677" />
非法的 XML:
<person />
假如您没有默认值选项,但是仍然希望强制作者提交属性的话,请使用关键词 #REQUIRED。
#FIXED
语法<!ATTLIST 元素名称 属性名称 属性类型 #FIXED "value">
例子
DTD:<!ATTLIST sender company CDATA #FIXED "Microsoft">
合法的 XML:
<sender company="Microsoft" />
非法的 XML:
<sender company="W3School" />
如果您希望属性拥有固定的值,并不允许作者改变这个值,请使用 #FIXED 关键词。如果作者使用了不同的值,XML 解析器会返回错误。
列举属性值
语法:<!ATTLIST 元素名称 属性名称 (en1|en2|..) 默认值>
DTD 例子:
<!ATTLIST payment type (check|cash) "cash">
XML 例子:
<payment type="check" />
或者
<payment type="cash" />
如果您希望属性值为一系列固定的合法值之一,请使用列举属性值。
实体
实体是用于定义引用普通文本或特殊字符的快捷方式的变量。
实体引用是对实体的引用。
实体可在内部或外部进行声明。一个内部实体声明
语法:<!ENTITY 实体名称 "实体的值">
例子:
DTD 例子:<!ENTITY writer "Bill Gates"> <!ENTITY copyright "Copyright W3School.com.cn">
XML 例子:
<author>&writer;©right;</author>
注释: 一个实体由三部分构成: 一个和号 (&), 一个实体名称, 以及一个分号 (;)。
一个外部实体声明
语法:<!ENTITY 实体名称 SYSTEM "URI/URL">
例子:
DTD 例子:<!ENTITY writer SYSTEM "http://www.w3school.com.cn/dtd/entities.dtd"> <!ENTITY copyright SYSTEM "http://www.w3school.com.cn/dtd/entities.dtd">
XML 例子:
<author>&writer;©right;</author>
验证
通过 XML 解析器进行验证
当试图打开某个 XML 文档时,XML 解析器有可能会产生错误。通过访问 parseError 对象,就可以取回引起错误的确切代码、文本甚至所在的行。
注释:load( ) 方法用于文件,而 loadXML( ) 方法用于字符串。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)
关闭验证
通过把 XML 解析器的 validateOnParse 设置为 “false”,就可以关闭验证。var xmlDoc = new ActiveXObject("Microsoft.XMLDOM") xmlDoc.async="false" xmlDoc.validateOnParse="false" 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)