文档类型定义DTD(Document Type Definition)--圣思园-WS-DTD详解


为什么使用 DTD

1,DTD 用来描述 XML 文档的结构
2,通过 DTD,您的每一个 XML 文件均可携带一个有关其自身格式的描述。
3,通过 DTD,独立的团体可一致地使用某个标准的 DTD 来交换数据。
4,而您的应用程序也可使用某个标准的 DTD 来验证从外部接收到的数据。
5,您还可以使用 DTD 来验证您自身的数据。

DTD文档组成

1,元素 ( ELEMENT ) 的定义规则。
2,元素之间的关系规则。
3,属性 ( ATTLIST ) 的定义规则。
4,可使用的实体 ( ENTITY ) 或符号 ( NOTATION ) 规则。

内部的 DOCTYPE 声明

假如 DTD 被包含在您的 XML 源文件中,它应当通过下面的语法包装在一个 DOCTYPE 声明中:
<!DOCTYPE 根元素 [DTD声明]>
.dtd 文件中是不能使用 DOCTYPE
 
带有 DTD 的 XML 文档实例:
 
     
    1. <?xml version="1.0" encoding="UTF-8" ?>
    2. <!DOCTYPE note [
    3. <!ELEMENT note (to,from,heading,body)><!--声明根元素note有4个子元素-->
    4. <!ELEMENT to (#PCDATA)>
    5. <!ELEMENT from (#PCDATA)>
    6. <!ELEMENT heading (#PCDATA)>
    7. <!ELEMENT body (#PCDATA)>
    8. ]>
    9. <note><!--这里所有定义的子元素都要被使用1次,使用顺序按照定义的顺序-->
    10. <to>George</to>
    11. <from>John</from>
    12. <heading>Reminder</heading>
    13. <body>Don't forget the meeting!</body>
    14. </note>
!DOCTYPE note (第二行)定义此文档是 note 类型的文档,note是根元素的名称。
!ELEMENT note (第三行)定义 note 元素有四个子元素:"to、from、heading、body"
!ELEMENT to  (第四行)定义 to 子 元素 数据类型 为 "#PCDATA" 
!ELEMENT from (第五行)定义 from  元素 数据类型 为 "#PCDATA"  
!ELEMENT heading (第六行)定义 heading  元素 数据类型 为 "#PCDATA"  
!ELEMENT body (第七行)定义 body  元素 数据类型 为 "#PCDATA" 
注意:例子中的定义关键字一定要大写,如DOCTYPEELEMENT#PCDATA
且元素名称与数据类型之间也要有空格

外部文档声明:

假如 DTD 位于 XML 源文件的外部,那么它应通过下面的语法被封装在一个 DOCTYPE 定义中:
<!DOCTYPE 根元素 SYSTEM "DTD文件路径">
例:
F:/dream/圣思园/Web.Service/note.dtd
 
    
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!ELEMENT note (to,from,heading,body)>
  3. <!ELEMENT to (#PCDATA)>
  4. <!ELEMENT from (#PCDATA)>
  5. <!ELEMENT heading (#PCDATA)>
  6. <!ELEMENT body (#PCDATA)>
 
   
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE note SYSTEM "F:/dream/圣思园/Web.Service/note.dtd">
  3. <note>
  4. <to>George</to>
  5. <from>John</from>
  6. <heading>Reminder</heading>
  7. <body>Don't forget the meeting!</body>
  8. </note>
公用DTD:
有一种外部DTD,是由某个权威机构制定,供特定行业或公司,这种DTD又被称为公用DTD
    <!DOCTYPE 根元素名 PUBLIC “DTD-NAME” “DTD-URL”>
公用DTD与外部DTD区别在于:公用DTD使用PUBLIC代替了原来的SYSTEM,并增加了DTD标识名。


内外部DTD文档结合

<!DOCTYPE 根元素  SYSTEM "DTD文件路径" [DTD声明内容]>
F:/dream/圣思园/Web.Service/note.dtd
 
    
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!ELEMENT to (#PCDATA)>
  3. <!ELEMENT from (#PCDATA)>
  4. <!ELEMENT heading (#PCDATA)>
  5. <!ELEMENT body (#PCDATA)>
 
     
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE note SYSTEM "F:/dream/圣思园/Web.Service/note.dtd"[
  3. <!ELEMENT note (to,from,heading,body,name)>
  4. <!ELEMENT name (#PCDATA)>
  5. ]>
  6. <note>
  7. <to>George</to>
  8. <from>John</from>
  9. <heading>Reminder</heading>
  10. <body>Don't forget the meeting!</body>
  11. <name>z</name>
  12. </note>


XML 文档构建模块

XML 以及 HTML 文档的主要构建模块是类似 <body>....</body> 这样的标签。
所有的 XML 文档(以及 HTML 文档)均由以下简单的构建模块构成:
元素,属性,实体,PCDATA ,CDATA  

下面是每个构建模块的简要描述。
元素
元素是 XML 以及 HTML 文档的主要构建模块。
HTML 元素的例子是 "body" 和 "table"。
XML 元素的例子是 "note" 和 "message" 。
元素可包含文本、其他元素或者是空的。
空的 HTML 元素的例子是 "hr"、"br" 以及 "img"。
例:
<body>body text in between</body>
<message>some message in between</message>

属性
属性可提供有关元素的额外信息。
属性总是被置于某元素的开始标签中。
属性总是以名称/值的形式成对出现的。
下面的 "img" 元素拥有关于源文件的额外信息:
<img src="computer.gif" />元素的名称是 "img"。属性的名称是 "src"。属性的值是 "computer.gif"。
由于元素本身为空,它被一个 " /" 关闭。

实体
实体是用来定义普通文本的变量。实体引用是对实体的引用。
大多数同学都了解这个 HTML 实体引用:"&nbsp;"。
这个“无折行空格”实体在 HTML 中被用于在某个文档中插入一个额外的空格。
当文档被 XML 解析器解析时,实体就会被展开。
下面的实体在 XML 中被预定义:
实体引用字符
&lt;<
&gt;>
&amp;&
&quot;"
&apos;'

PCDATA(用于元素) 的意思是被解析的字符数据(parsed character data)。
可把字符数据想象为 XML 元素的开始标签与结束标签之间的文本。
PCDATA 是会被解析器解析的文本。这些文本将被解析器检查实体以及标记。
文本中的标签会被当作标记来处理,而实体会被展开。
不过, 被解析的字符数据不应当包含任何 &、< 或者 > 字符;需要使用 &amp;、&lt; 以及 &gt; 实体来分别替换它们。
CDATA(用于属性)
CDATA 的意思是字符数据(character data)。
CDATA 是不会被解析器解析的文本。在这些文本中的标签不会被当作标记来对待,其中的实体也不会被展开。

DTD - 元素

在 DTD 中,XML 元素通过元素声明来进行声明。
元素声明使用下面的语法:
<!ELEMENT 元素名称 类别> 或者   <!ELEMENT 元素名称 (元素内容)>

元素类别:

EMPTY-该元素不能包含子元素和文本,但可以有属性-(空元素)

ANY-该元素可以包含任何在DTD中定义的元素内容

#PCDATA-可以包含任何字符数据,但是不能在其中包含任何子元素

纯元素类型-只包含子元素,并且这些子元素外没有文本

混合类型-包含子元素和文本数据的混合

空元素
空元素通过类别关键词EMPTY进行声明:
<!ELEMENT 元素名称 EMPTY>
例: <!ELEMENT br EMPTY>
XML例子: <br />
只有 PCDATA 的元素
只有 PCDATA 的元素通过圆括号中的 #PCDATA 进行声明:
<!ELEMENT 元素名称 (#PCDATA)>
例: <!ELEMENT from (#PCDATA)>
带有任何内容的元素
通过类别关键词 ANY 声明的元素,可包含任何可解析数据的组合:
<!ELEMENT 元素名称 ANY>
例: <!ELEMENT note ANY>
 
    
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE note [
  3. <!ELEMENT note (to,from*)>
  4. <!ELEMENT to ANY>
  5. <!ELEMENT from (#PCDATA)>
  6. ]>
  7. <note>
  8. <to><from>X</from></to>
  9. </note>
带有子元素(序列)的元素
带有一个或多个子元素的元素通过圆括号中的子元素名进行声明:
<!ELEMENT 元素名称 (子元素名称 1)>
或者
<!ELEMENT 元素名称 (子元素名称 1,子元素名称 2,.....)>
例: <!ELEMENT note (to,from,heading,body)>
当子元素按照由逗号分隔开的序列进行声明时,这些子元素必须按照相同的顺序出现在文档中。
在一个完整的声明中,子元素也必须被声明,同时子元素也可拥有子元素。
"note" 元素的完整声明是:
 
    
    1. <!ELEMENT note (to,from,heading,body)>
    2. <!ELEMENT to (#PCDATA)>
    3. <!ELEMENT from (#PCDATA)>
    4. <!ELEMENT heading (#PCDATA)>
    5. <!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"。
 
    
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE note [
  3. <!ELEMENT note (#PCDATA|to|from|header|message)*>
  4. <!ELEMENT to (#PCDATA)>
  5. <!ELEMENT from (#PCDATA)>
  6. <!ELEMENT header (#PCDATA)>
  7. <!ELEMENT message (#PCDATA)>
  8. ]>
  9. <note>
  10. abc
  11. <to>to</to>
  12. <from>from</from>
  13. def
  14. </note>

符号

用途

示例

示例说明

(  )

用来给元素分组

(古龙|金庸|梁羽生),(王朔|余杰),毛毛

分成三组

|

在列出的对象中选择一个

(男人|女人)

表示男人或者女人必须出现,两者选一

+

该对象最少出现一次,可以出现多次 (1或多次)

(成员+

表示成员必须出现,而且可以出现多个成员

*

该对象允许出现零次到任意多次(0到多次)

(爱好*

爱好可以出现零次到多次

?

该对象可以出现,但只能出现一次 (01)

(菜鸟?

菜鸟可以出现,也可以不出现,如果出现的话,最多只能出现一次

,

对象必须按指定的顺序出现

(西瓜,苹果,香蕉)

表示西瓜、苹果、香蕉必须出现,并且按这个顺序出现


DTD - 属性

在 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 名称,NMTOKEN是CDATA的一个子集,表示属性值必须是英文字母、数字、句号、破折号、下划线或冒号,属性值不能含有空格
NMTOKENS值为合法的 XML 名称的列表,NMTOKENS与NMTOKEN类似,包含多个由空格分隔的字符
ENTITY值是一个实体
ENTITIES值是一个实体列表
属性的默认值
解释
属性的默认值
#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和ENTITIES类型的属性其属性值只能是未解析的实体,与外部数据相连。如图像文件,音像文件等。
注意:
一旦声明某个属性的类型是entity或entities,就意味着该属性值只能是一个或多个未解析的实体,而不是已经解析的实体。对于未解析的实体而言,不能通过普通实体引用方式去引用,他们只能作为entity或entities类型的属性值。


DTD - 实体

实体是用于定义引用普通文本或特殊字符的快捷方式的变量。
          实体是包含了文档片段的虚拟存储单元,可用来存储XML声明、DTD、其他形式的文本及二进制数据等。简单来讲就是一段代码或数据的代称,这个代称即为实体 的名字。
          当需要在文档中引用某段代码或数据时,可以引用与段代码或数据相对应的实体名称来代替实体的具体内容。具有正确性检查功能的XML处理器在提交文档给最终应用程序之前或在显示文档以前,将先把所有不同的实体引用替换为与其对应的具体内容,从而构成一个结构完整的文档。

          按照实体的具体内容来分类,实体可分为可解析与不可解析两类。可解析实体的具体内容为简单的字符、数字、文本块,而不可解析实体的具体内容则为图片、声音等二进制文件。
          按照逻辑存储来分类,实体可分为内部实体与外部实体两类。内部实体的内容是在文档内部设定的;而外部实体则是一个外部独立的物理存储对象,如某个外部文件。
          按照使用的范围来分类,实体可分为一般实体与参数实体两类。一般实体都用来构成文档的具体内容,可出现在XML文档中,也可出现在DTD中;而参数实体只能出现在DTD中,不能出现在XML文档中
实体引用是对实体的引用。
实体可在内部或外部进行声明。
一个内部实体声明
语法: <!ENTITY 实体名称 "实体的值">
例: DTD:
<!ENTITY writer "Bill Gates">
<!ENTITY copyright "Copyright W3School.com.cn">
XML:  <author>&writer;&copyright;</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;&copyright;</author>

类型

普通实体

参数实体

使用场合

用在XML文档中

只用在DTD中元素和属性的声明中

声明方式

内部

<!ENTITY 实体名 "文本内容">

<!ENTITY % 实体名 "文本内容">

外部

<!ENTITY 实体名 SYSTEM"外部文件URL地址">

<!ENTITY % 实体名 SYSTEM "外部文件URL地址">

引用方式

&实体名;

%实体名;

参数实体
 F:\dream\圣思园\Web.Service\note.dtd
 
    
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!ENTITY % p "to">
  3. <!ELEMENT %p; (#PCDATA)>
  4. <!ATTLIST %p; addr CDATA #FIXED 'sp'>
 
     
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE note SYSTEM "F:\dream\圣思园\Web.Service\note.dtd"[
  3. <!ELEMENT note (to) >
  4. ]>
  5. <note>
  6. <to addr = "sp">nn</to>
  7. </note>

DTD - 符号

NOTATION   主要是用来表明文档中需要来自外部源的数据,而该数据XML本身是不能进行解析的,比如各种格式的二进制文件(比如图形文件、声音文件等),需要外部的应用程序进行处理。
NOTATION  声明的语法格式如下:
  <!NOTATION NAME ExternalID>
 需要注意的是NAME必须由字母、数字、句点、破折号或冒号组成,并且第一个字符必须为字母或者是下划线。下面的例子表示GIF图象作为不解析的外部内容。
 
       
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!NOTATION gif SYSTEM "iexplore.exe">
  3. <!ENTITY logo SYSTEM "http://web/category/sg.gif" NDATA gif>
  4. <!-- 这里NDATA表示XML不解析该数据 -->
  5. <!ELEMENT PIC EMPTY>
  6. <!ATTLIST PIC loc ENTITY #REQUIRED>
然后,在具体的实例化文档中包含下面一行代码:
  <PIC loc="&logo;" /> 
根据DTD定义,loc属性值是一个不解析的实体。解析器可以根据DTD定义知道这一点,然后它就不对其进行解析,也不会象解析实体一样把它包括到XML文档里面。同时,XML解析器将通知iexplore.exe该引用的存在。







转载于:https://www.cnblogs.com/java-z/p/3826629.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值