最新消息:

XML笔记2——DTD详解

Web前端开发 大步 1040浏览 0评论

目前两种语义约束的方式:

  1. DTD,简单易用,但功能较弱
  2. XML Schema,功能强大,但复杂

为什么有语义约束,这就类似于通信协议一样,只有双方使用同样的协议,才能明白对方传达的信息。

DTD(Document Type Definition,即文档类型定义) ,见w3cshoocl:http://www.w3school.com.cn/dtd/dtd_intro.asp

Dtd约束包括那几个方面

 

1、  定义xml的根元素、内容和结构

 

2、  定义xml文档中可以接受那些元素

 

3、  定义xml文档里每个元素接受的合法内容,包括是否为空,是可以是文本,可以接受那些子元素,子元素出现的顺序和子元素出现次数等。

 

4、  定义xml文档中每个元素能接受那些属性

 

5、  定义xml文档中每个属性的类型,能接受那些值,以及元素对属性的约束等。

 

6、  定义属性的固定值和默认值

 

7、  定义xml文档或dtd中可以使用的实体。

 

Dtd有作用

 

1、  Dtd采用了非xml的语法描述语义约束,可以提供如下功能

 

2、  通过使用dtd可以让每个xml文件带有一个有关其自身的格式描述

 

3、  不同的公司、组织可一致地使用某个标准的dtd来交换数据

 

4、  应用程序也可以使用某个标准的dtd验证所介绍的xml文档是否符合语义约束

 

5、  开发者也可以使用dtd来验证所创建的xml文档。

引入DTD 三种方式:

  • 内部DTD
  • 外部DTD
  • 公用DTD

内部DTD

指将DTD与xml 数据定义放在同一份文档中,即将DTD定义在xml文档内部,紧跟在xml声明和处理指令之后。

<!DOCTYPE 根元素 [元素声明]>

下面的例子:

<?xml version="1.0" encoding="GBK" standalone="yes"?>

<!-- 内部DTD,内部DTD指定了文档根元素:书籍列表 -->

<!DOCTYPE 书籍列表[

<!ELEMENT 书籍列表 (计算机书籍)*>

<!ELEMENT 计算机书籍 (书名,作者,价格,简要介绍)>

<!ELEMENT 书名 (#PCDATA)>

<!ELEMENT 作者 (#PCDATA)>

<!ELEMENT 价格 (#PCDATA)>

<!ELEMENT 简要介绍 (#PCDATA)>

]>

<!-- 下面是XML文档部分 -->

<书籍列表>

<计算机书籍>

<书名>Struts 2.1权威指南</书名>

<作者>李刚</作者>

<价格>79.00</价格>

<简要介绍>

该书详细介绍了Struts 2.1的各种用法

</简要介绍>

</计算机书籍>

<计算机书籍>

<书名>轻量级Java EE企业开发实战</书名>

<作者>李刚</作者>

<价格>89.00</价格>

<简要介绍>

该书主要介绍了一种流行的轻量级企业应用架构

</简要介绍>

</计算机书籍>

</书籍列表>

但是每一份xml文档都写入一次又太麻烦了,所以,就有了外部DTD

外部DTD

类似css一样,将dtd与xml文档分离。

<!DOCTYPE 根元素 SYSTEM "文件名">

看下面的例子:

book.dtd的代码如下:

<?xml version="1.0" encoding="GB2312"?>

<!ELEMENT 书籍列表 (计算机书籍)*>

<!ELEMENT 计算机书籍 (书名,作者,价格,简要介绍)>

<!ELEMENT 书名 (#PCDATA)>

<!ELEMENT 作者 (#PCDATA)>

<!ELEMENT 价格 (#PCDATA)>

<!ELEMENT 简要介绍 (#PCDATA)>

下面是使用上述DTD的xml 文档:

<?xml version="1.0" encoding="GB2312"?>

<!DOCTYPE 书籍列表

SYSTEM "book.dtd">

<书籍列表>

<计算机书籍>

<书名>Struts 2.1权威指南</书名>

<作者>李刚</作者>

<价格>79.00</价格>

<简要介绍>

该书详细介绍了Spring2.0的用法

</简要介绍>

</计算机书籍>

<计算机书籍>

<书名>轻量级Java EE企业开发实战</书名>

<作者>李刚</作者>

<价格>89.00</价格>

<简要介绍>

该书主要介绍了一种流行的轻量级企业应用架构

</简要介绍>

</计算机书籍>

</书籍列表>

公用DTD

即一种有某个权威机构指定的外部DTD

<!DOCTYPE 根元素

PUBLIC "DTD的标识名" "公用DTD'的URL">

DTD的文档结构如下:

第一行是DTD声明部分 该声明与xml文档的生命语法格式相同

0到多个注释部分,DTD注释与xml文档的注释完全相同

0到多个<!ELEMENT…..>定义 每个它就是一个xml元素

0到多个<!ATTLIST…..>定义每个它就是一个xml元素的属性

0到多个<!ENTITY…..>定义每个它就是一个实体

0到多个<!NOTATION…..>定义 每个它定义一个符号

1、 定义元素

元素类型的定义的全称是:Element Type Defintion,简称ETD,它不但会定义每个文件中可能存在的元素,给元素的名称,而且会定义元素的具体类型。

元素类型描述主要有5种:

1、  任意类型

可以是以下四种的内容

语法格式:

<!ELEMENT 元素名 ANY>

2、  字符串值

3、  空元素 <br/>

4、  包含子元素

5、  混合类型

任意类型语法:

<!ELEMENT 元素名 ANY>

<!--任意类型实例-->

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE book[

<!ELEMENT book ANY>

]>

无效的xml文档但是格式良好的xml文档

定义空元素语法:

<!--空元素-->

<!ELEMENT 元素名 EMPTY>

实例

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE book[

<!ELEMENT book EMPTY>

]>

有效的xml文档

定义字符串内容的元素:

<!--定义字符串内容的元素-->

<!ELEMENT 元素名 (#PCDATA)>

实例:

 

<?xml version="1.0" encoding="UTF-8"?>

<!ELEMENT book (computer)*>

<!ELEMENT computer (book_name,price,author)>

<!ELEMENT book_name (#PCDATA)>

<!ELEMENT price (#PCDATA)>

<!ELEMENT author (#PCDATA)>

定义混合内容

<!--定义混合内容-->

<!ELEMENT 父元素名(#PCDATA|子元素1|子元素2|子元素3|........)*>  竖线( | )并不是互斥,而只是表示这些子元素能无序地重复出现,出现多少次不受限制。

注意:1、#PCDATA必须放在最前面

2、#PCDATA只能用|与各个子元素分隔

3、不要试图在各个子元素之后添加?、*、+等表示频率的修饰符

实例如下:

mixed.xml

<?xml version="1.0" encoding="GB2312"?>

<!DOCTYPE 喜欢的游戏 SYSTEM

"mixed.dtd">

<喜欢的游戏>

游戏和编程是类似的,都是一种兴趣

<!-- 下面元素内容中包含2个子元素和字符串 -->

<游戏>

<游戏类型>动作格斗</游戏类型>

<游戏名称>侍魂</游戏名称>

适合释放紧张的、沉闷的感觉

</游戏>

<!-- 下面元素内容中包含2个子元素和字符串 -->

<游戏>

放松、舒缓心情的好游戏。

<游戏名称>雷电</游戏名称>

<游戏类型>飞行射击</游戏类型>

</游戏>

<!-- 下面元素内容中只有一个子元素 -->

<游戏>

<游戏名称>雷电</游戏名称>

</游戏>

<!-- 下面元素内容包含2个重复的子元素 -->

<游戏>

<游戏名称>雷电</游戏名称>

<游戏名称>侍魂</游戏名称>

</游戏>

</喜欢的游戏>

使用的DTD ,为mixed.dtd

<?xml version="1.0" encoding="GB2312"?>

<!ELEMENT 喜欢的游戏 (#PCDATA | 游戏)*>

<!ELEMENT 游戏 (#PCDATA | 游戏名称 | 游戏类型)*>

<!ELEMENT 游戏名称 (#PCDATA)>

<!ELEMENT 游戏类型 (#PCDATA)>

 定义子元素

1、  有序的子元素(,)

(,)用于分隔有序的子元素。

如有下面的sequence.dtd:

<?xml version="1.0" encoding="GB2312"?>

<!ELEMENT 书籍列表 (计算机书籍)*>

<!ELEMENT 计算机书籍 (书名,作者,价格,简要介绍)>

<!ELEMENT 书名 (#PCDATA)>

<!ELEMENT 作者 (#PCDATA)>

<!ELEMENT 价格 (#PCDATA)>

<!ELEMENT 简要介绍 (#PCDATA)>

则子元素的顺序必须按逗号顺序来定义。所以,有效的xml文档见sequence.xml:

<?xml version="1.0" encoding="GB2312"?>

<!DOCTYPE 书籍列表

SYSTEM "sequence.dtd">

<书籍列表>

<计算机书籍>

<书名>Struts 2.1权威指南</书名>

<作者>李刚</作者>

<价格>79.00</价格>

<简要介绍>

该书详细介绍了Struts 2.1各功能和用法

</简要介绍>

</计算机书籍>

<计算机书籍>

<书名>轻量级Java EE企业开发实战</书名>

<作者>李刚</作者>

<价格>89.00</价格>

<简要介绍>

该书主要介绍了一种流行的轻量级企业应用架构

</简要介绍>

</计算机书籍>

</书籍列表>

2、  互斥的子元素

互斥的子元素表明一系列的子元素中只能出现其中之一。

互斥元素用竖线(|)分隔。

实例:

choice.dtd:

<?xml version="1.0" encoding="GB2312"?>

<!ELEMENT 书籍列表 (计算机书籍)*>

<!ELEMENT 计算机书籍 (书名|作者|价格|简要介绍)>

<!ELEMENT 书名 (#PCDATA)>

<!ELEMENT 作者 (#PCDATA)>

<!ELEMENT 价格 (#PCDATA)>

<!ELEMENT 简要介绍 (#PCDATA)>

对应的choice.xml:

<?xml version="1.0" encoding="GB2312"?>

<!DOCTYPE 书籍列表

SYSTEM "choice.dtd">

<书籍列表>

<计算机书籍>

<书名>Struts 2.1权威指南</书名>

</计算机书籍>

<计算机书籍>

<价格>99.00</价格>

</计算机书籍>

</书籍列表>

3、  子元素出现的频率

          +: 一次或多次 (书+)

          ?: 0次或一次 (书?)

                 *: 0次或多次  (书*)

注意:混合类型的频率只能安如下方式加:

<!ELEMENT computer (#PCDATA|book_name|price|author)*>

//#PCDATA以它开头的是混合类型 频率只能在最后加

        4.组合子元素

DTD允许使用圆括号将多个子元素括起来形成元素组,元素组内的各个子元素之间可用英文逗号分隔,以表示元素组之内各个元素有序,也可以用竖线分隔,比表示元素组之内各元素互斥。

将指定元素编成一个元素组后,DTD还允许使用表示频率的特殊标记紧跟该 元素组,用以表示该元素组的出现频率。

第一个例子:

group.dtd:

<?xml version="1.0" encoding="GB2312"?>

<!ELEMENT 书籍列表 (计算机书籍)*>

<!-- 将 书名、作者 定义成组,该元素组可出现1~多次 -->

<!ELEMENT 计算机书籍 ((书名,作者)+,价格,简要介绍)>

<!ELEMENT 书名 (#PCDATA)>

<!ELEMENT 作者 (#PCDATA)>

<!ELEMENT 价格 (#PCDATA)>

<!ELEMENT 简要介绍 (#PCDATA)>

group.xml:

<?xml version="1.0" encoding="GB2312"?>

<!DOCTYPE 书籍列表 SYSTEM

"group.dtd">

<书籍列表>

<计算机书籍>

<书名>疯狂Java讲义</书名>

<作者>李刚</作者>

<书名>轻量级Java EE企业应用实战</书名>

<作者>李刚</作者>

<价格>99.00</价格>

<简要介绍>

深入而全面地介绍了Java编程的各方面的内容

</简要介绍>

</计算机书籍>

</书籍列表>

第二个例子:

group2.dtd:

<?xml version="1.0" encoding="GB2312"?>

<!ELEMENT 书籍列表 (计算机书籍)*>

<!-- 将 书名、作者 定义成组,价格、简要介绍两个元素成组

两个元素组之间互斥 -->

<!ELEMENT 计算机书籍 ((书名+,作者)|(价格,简要介绍))>

<!ELEMENT 书名 (#PCDATA)>

<!ELEMENT 作者 (#PCDATA)>

<!ELEMENT 价格 (#PCDATA)>

<!ELEMENT 简要介绍 (#PCDATA)>

对应的group2.xml:

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE 书籍列表 SYSTEM

"group2.dtd">

<书籍列表>

<计算机书籍>

<!-- 下面是出现 书名、作者 元素组,

其中书名元素出现了2次 -->

<书名>疯狂Java讲义</书名>

<书名>疯狂XML讲义</书名>

<作者>李刚</作者>

</计算机书籍>

<计算机书籍>

<!-- 下面是出现 价格、简要介绍 元素组 -->

<价格>99.00</价格>

<简要介绍>深入介绍XML、DTD、Schema、XQuery

XSLT、XPATH、DOM、SAX、JAXP、SOAP、WSDL等相关知识。

</简要介绍>

</计算机书籍>

</书籍列表>

5.无序的子元素

DTD中没有专门为定义无序子元素提供语法,所以,我们需要借助元素组来实现。

用于表示频率的特殊标记不仅可以紧跟在元素之后,还可以紧跟在以括号扩起的元素组之后,表示该组元素出现的频率。

实例:

noSequence.dtd:

<?xml version="1.0" encoding="GB2312"?>

<!ELEMENT 书籍列表 (计算机书籍)*>

<!ELEMENT 计算机书籍 (书名|作者|价格|简要介绍)+>

<!ELEMENT 书名 (#PCDATA)>

<!ELEMENT 作者 (#PCDATA)>

<!ELEMENT 价格 (#PCDATA)>

<!ELEMENT 简要介绍 (#PCDATA)>

对应的noSequence.xml:

<?xml version="1.0" encoding="GB2312"?>

<!DOCTYPE 书籍列表 SYSTEM

"noSequence.dtd">

<书籍列表>

<计算机书籍>

<作者>李刚</作者>

<作者>作者2</作者>

</计算机书籍>

<计算机书籍>

<书名>轻量级Java EE企业开发实战</书名>

<作者>李刚</作者>

<价格>89.00</价格>

<简要介绍>

该书主要介绍了一种流行的轻量级企业应用架构

</简要介绍>

</计算机书籍>

<计算机书籍>

<作者>李刚</作者>

<书名>疯狂XML讲义</书名>

<简要介绍>深入介绍XML、DTD、Schema、XQuery

XSLT、XPATH、DOM、SAX、JAXP、SOAP、WSDL等相关知识。

</简要介绍>

<价格>69</价格>

</计算机书籍>

</书籍列表>

            

定义元素属性:

1、  定义属性

<!ATTLIST属性所属元素  属性名  属性类型[元素对属性的约束][默认值]>

元素对属性的约束|默认值是可选的对于它们的使用有如下的情况:

1、  在没有指定”元素对属性的约束”时,必须为该属性增加默认值。

2、  在元素对属性的约束是:#REQUIRED时,不能为该属性指定默认值。

3、  在元素对属性的约束是:#IMPLIED时,不能为该属性指定默认值

4、  在元素对属性的约束是:#FIXED时,必须为该属性指定默认值

#REQUIRED:必须的属性

#IMPLIED:可有可无

#FIXED:固定值

<水果 品名=”苹果” 颜色=”绿色”>关于水果的元素</水果>

对于#REQUIRED属性的实例:

required.dtd:

<?xml version="1.0" encoding="GB2312"?>

<!ELEMENT 计算机书籍 ((书名, 作者, 价格, 简要介绍))>

<!ELEMENT 简要介绍 (#PCDATA)>

<!ELEMENT 作者 (#PCDATA)>

<!ATTLIST 作者 地址 CDATA #REQUIRED>

<!ELEMENT 价格 (#PCDATA)>

<!ELEMENT 书籍列表 ((计算机书籍))>

<!ELEMENT 书名 (#PCDATA)>

对应的required.xml:

<?xml version="1.0" encoding="GB2312"?>

<!DOCTYPE 书籍列表 SYSTEM "required.dtd">

<书籍列表>

<计算机书籍>

<书名>Struts 2.1权威指南</书名>

<作者 地址="广州">kongyeeku</作者>

<价格>79.00</价格>

<简要介绍>

该书详细介绍了Struts 2.1各种功能和用法

</简要介绍>

</计算机书籍>

</书籍列表>

使用#FIXED 约束定义某个属性:

fixex.dtd:

<?xml version="1.0" encoding="GB2312"?>

<!ELEMENT 书籍列表 (计算机书籍*)>

<!ELEMENT 计算机书籍 ((书名, 作者, 价格, 简要介绍))>

<!ELEMENT 简要介绍 (#PCDATA)>

<!ELEMENT 作者 (#PCDATA)>

<!ATTLIST 作者 地址 CDATA #FIXED "广州">

<!ELEMENT 价格 (#PCDATA)>

<!ELEMENT 书名 (#PCDATA)>

意味着使用<作者 .../>元素时,可以不指定“地址”属性。如果不提供“地址”属性,xml解析器将自动为<作者 .../>元素增加“地址”属性,且其属性值为“广州";也可以为<作者 .../>元素指定”地址“属性,但指定”地址“属性时,其值必须为”广州“。

所以下面的文档是无效的:

fixed.xml:

<?xml version="1.0" encoding="GB2312"?>

<!DOCTYPE 书籍列表

SYSTEM "fixed.dtd">

<书籍列表>

<计算机书籍>

<书名>Struts 2.1权威指南</书名>

<作者>李刚</作者>

<价格>79.00</价格>

<简要介绍>

该书详细介绍了Struts 2.1各种功能和用法

</简要介绍>

</计算机书籍>

<计算机书籍>

<书名>轻量级J2EE企业开发实战</书名>

<作者 地址="上海">李刚</作者>

<价格>63</价格>

<简要介绍>

该书主要介绍了一种流行的轻量级企业应用架构

</简要介绍>

</计算机书籍>

</书籍列表>

定义属性类型

以下是属性类型的选项:

类型 描述
CDATA 值为字符数据 (character data)
(en1|en2|..) 此值是枚举列表中的一个值
ID 值为唯一的 id
IDREF 值为另外一个元素的 id
IDREFS 值为其他 id 的列表
NMTOKEN 值为合法的 XML 名称
NMTOKENS 值为合法的 XML 名称的列表
ENTITY 值是一个实体
ENTITIES 值是一个实体列表
NOTATION 此值是符号的名称
xml: 值是一个预定义的 XML 值
  1. CDATA型

CDATA   型表明属性值为不包含“< ”和“"”的任意字符串,如果属性值中需要包含

“<”和“"”,则可使用特殊字符来代替。

  1. Enumerated型

如果属性值并不是任意的字符串,而是在几个可能的值中进行选择,如书籍的“类别”

属性,其值可为“文艺”,也可为“自然科学”,而不可能为其他情况时,则可以将书籍

的“类别”属性设定为Enumerated 型。

  1. ID型

当元素的某个属性值是不能重复时,如书籍的ISBN  属性、个人的“身份证号”属性

等,要定义这样的属性则需使用属性的ID 类型。在一个XML  文档中,所有元素的ID

类型属性的属性值必须是唯一的,不可重复,另外,一个元素不能有超过一个ID 类型的

属性。

  1. IDREF与IDREFS 型

IDREF 为Identifier Reference 的缩写,IDREF 与ID 类型属性的关系为子元素与父元素

的关系,即IDREF 类型属性的值必须是其他元素的ID 类型属性的值,且该ID 类型属性的

值必须在文档的其他地方被设定过。IDREFS                 类型属性的属性值可有多个,每一个都必须

是在文档其他地方被设定了的ID 类型属性的值,而这多个属性值之间用空格隔开。

  1. ENTITY与ENTITIES型

ENTITY  类型的属性提供了把外部二进制形式的文件(如.jpeg、.mp3  等)和外部不可解

析实体链接到XML文档的功能。因此其属性值也必须为不可解析的链接外部实际数据的

通用实体名。ENTITIES  类型属性的属性值可由多个不可解析的外部实体名称组成,各实体

名称之间使用空格隔开。

  1. NMTOKEN与NMTOKENS 型

NMTOKEN 类型的属性限定属性值是有效的XML 名称,这个属性值可以由英文、数

字、“.”、 “_ ”、“-”、“:”等组成,这里有几点需要注意。

(1) 不能包括空格。

(2) 以上字符中除“:”以外,其他字符都可以作为开头字符。

(3) “:”可以出现在中间,但由于它是命名域的关键字符,所以一般不提倡使用。

正因为NMTOKEN 类型的属性对于字符的严格要求,使得它在一些常用编程语言中,

都是合法的数据,这就为这些编程语言对XML 文档数据的操作打下了良好的基础。

NMTOKENS 类型的属性具有与NMTOKEN 属性相近的形式。这种类型的属性可以使如

下情况合法——属性由若干XML 名称组成,彼此间由空格隔开。通常可为使用NMTOKEN

属性相同的理由而使用NMTOKENS 属性,但仅仅在需要多个名字的时候。

 

  1. NOTATION型

XML 文档中引入了外部不可解析的实体后,解析器无法解析这些二进制文件,这时,

就可以使用NOTATION类型的属性为这些二进制文件指定与其对应的应用软件以对其进

行处理。

枚举类型:

实例:

enumerated.dtd:

<?xml version="1.0" encoding="GB2312"?>

<!ELEMENT 购物车 (肉* , 水果*)>

<!ELEMENT 肉 EMPTY>

<!ELEMENT 水果 EMPTY>

<!ATTLIST 肉 类型 (鸡肉|牛肉|猪肉|鱼肉) #REQUIRED>

<!ATTLIST 水果 类型 (苹果|梨|桔子) #REQUIRED>

对应到 enumerated.xml:

<?xml version="1.0" encoding="GB2312"?>

<!DOCTYPE 购物车 SYSTEM "enumerated.dtd">

<购物车>

<肉 类型="猪肉"/>

<肉 类型="鸡肉"/>

<水果 类型="苹果"/>

<水果 类型="梨"/>

</购物车>

ID、IDREF、IDREFS 类型:

实例:

idandidref.dtd:

<?xml version="1.0" encoding="GB2312"?>

<!ELEMENT beans (bean|object)*>

<!ELEMENT bean (property*)>

<!ELEMENT object EMPTY>

<!ELEMENT property EMPTY>

<!ATTLIST bean id ID #REQUIRED>

<!ATTLIST object id ID #REQUIRED>

<!ATTLIST property name CDATA #REQUIRED>

<!ATTLIST property ref IDREF #IMPLIED>

<!ATTLIST property set IDREFS #IMPLIED>

对应的idandidref.xml:

<?xml version="1.0" encoding="GB2312"?>

<!DOCTYPE beans SYSTEM "idandidref.dtd">

<beans>

<bean id="chin"/>

<object id="cat"/>

<object id="_jerfied-cat"/>

<bean id="foo">

<property ref="chin" name="man"/>

</bean>

<bean id="bar">

<property set="cat _jerfied-cat" name="pet"/>

</bean>

</beans>

NMTOKEN和NMTOKENS类型:

NMTOKEN 比ID类型更宽松的类型,它只要求该属性值是个合法的xml标识即可。也就是说NMTOKEN类型的属性值也是字符串数据,但NMTOKEN 约束比CDATA约束要严格,即NMTOKEN类型的属性值中能出现的字符要少。

举个实例区分:

cdata.dtd:

<?xml version="1.0" encoding="GB2312"?>

<!ELEMENT 书籍列表 (计算机书籍)*>

<!ELEMENT 计算机书籍 (书名,作者,价格,简要介绍)>

<!ELEMENT 书名 (#PCDATA)>

<!ELEMENT 作者 (#PCDATA)>

<!ELEMENT 价格 (#PCDATA)>

<!ELEMENT 简要介绍 (#PCDATA)>

<!ATTLIST 作者 地址 CDATA #REQUIRED>

nmtoken.dtd:

<?xml version="1.0" encoding="GB2312"?>

<!ELEMENT 书籍列表 (计算机书籍)*>

<!ELEMENT 计算机书籍 (书名,作者,价格,简要介绍)>

<!ELEMENT 书名 (#PCDATA)>

<!ELEMENT 作者 (#PCDATA)>

<!ELEMENT 价格 (#PCDATA)>

<!ELEMENT 简要介绍 (#PCDATA)>

<!ATTLIST 作者 地址 NMTOKEN #REQUIRED>

但是下面的xml文档对于cdata.dtd是有效的,对于nmtoken.dtd是无效的:

<?xml version="1.0" encoding="GB2312"?>

<!DOCTYPE 书籍列表

SYSTEM "cdata.dtd">

<书籍列表>

<计算机书籍>

<书名>轻量级Java EE企业开发实战</书名>

<作者 地址="广州#">李刚</作者>

<价格>63</价格>

<简要介绍>

该书主要介绍了一种流行的轻量级企业应用架构

</简要介绍>

</计算机书籍>

</书籍列表>

因为NMTOKEN类型的属性值里不能包含 # 符号。

定义实体:

就是用一个字符串代替另一个字符串。类似c语言中的宏变量。作用:

  • 提高代码复用,方便修改、维护xml文档
  • 使用某些特殊符号,如替代小于号之类的,防止xml解析器混淆
  • 较少字符输入量

实体的分类

  1.     按照实体的具体内容来分类,实体可分为可解析与不可解析两类。可解析实体的具体内容为简单的字符、数字、文本块,而不可解析实体的具体内容则为图片、声音等二进制文件。
  2. 按照逻辑存储来分类,实体可分为内部实体与外部实体两类。内部实体的内容是在文档内部设定的;而外部实体则是一个外部独立的物理存储对象,如某个外部文件。
  3.     按照使用的范围来分类,实体可分为一般实体与参数实体两类。一般实体都用来构成文档的具体内容,可出现在XML               文档中,也可出现在DTD中;而参数实体只能出现在DTD中,不能出现在XML 文档中。

1. 内部一般实体

内部一般实体就是在文档实体内部定义和使用的实体,其内容通常是一段文本字符。

这种实体要在DTD 中通过DTD 语句的定义,可以在XML 文档中使用,也可在DTD 中使

用。其定义的语法格式如下:

语法:

<!ENTITY 实体名称 "实体的值">

例子:

DTD 例子:

<!ENTITY writer "Bill Gates">

<!ENTITY copyright "Copyright W3School.com.cn">

XML 例子:

<author>&writer;©right;</author>

注释: 一个实体由三部分构成: 一个和号 (&), 一个实体名称, 以及一个分号 (;)。

例子2:

例 内部一般实体的使用,代码如下

<?xml version="1.0" encoding="gb2312"?>

<!DOCTYPE bookinfo [

<!ELEMENT bookinfo (title, author, publish, price)>

<!ELEMENT title (#PCDATA)>

<!ELEMENT author (#PCDATA)>

<!ELEMENT publish (publisher, ISBN, pubdate)>

<!ELEMENT publisher (#PCDATA)>

<!ELEMENT ISBN (#PCDATA)>

<!ELEMENT pubdate (#PCDATA)>

<!ELEMENT price (#PCDATA)>

<!ENTITY thepublisher "高等教育出版社">

]>

<bookinfo>

<title>计算机导论</title>

<author>丁跃潮等</author>

<publish>

<publisher> &thepublisher; </publisher>

<ISBN>7-04-014768-8</ISBN>

<pubdate>2004.6</pubdate>

</publish>

<price>19.7</price>

</bookinfo>

当内部一般实体在DTD 中引用时,有以下几方面需注意。

(1) 不能在元素及属性的声明中引用内部一般实体,如下面的语句即为非法的:

<!ENTITY  pcd  (#PCDATA)>

<!ELEMENT  title  &pcd;>

(2) 在语句中不能出现循环,如下面的语句即为非法的:

 

<!ENTITY  thepub  "北大&pub;">

<!ENTITY  pub  "出版社&thepub;">

  2. 外部一般实体

所谓外部一般实体就是在文档实体以外定义的,要通过一个URL 才能引用到的实体。

外部一般实体为独立的文件,可被多个文档所引用。正因为每一个完整的XML  文档都是一个合法的实体,所以XML 通过对外部一般实体的引用,可以在一个XML 文档中嵌入另一个XML 文档,或者将多个文档组合成一个文档。其定义的语法格式如下:

 

<!ENTITY 实体名称 SYSTEM "实体值所在的文件的URI/URL">

其中,URL  为引用的外部实体的URL  地址。引用外部一般实体也与引用内部一般实

体的方法一样:

&Eentity_name;

例子1:

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>

例子2: 假如有一个XML 文档code4_14out.xml 如下:

<?xml version="1.0" encoding="gb2312" ?>

<publish>

<publisher>高等教育出版社</publisher>

<ISBN>7-04-014768-8</ISBN>

<pubdate>2004.6</pubdate>

</publish>

可以通过下面的例子把它作为外部实体来引用。

例  外部一般实体的使用,代码如下

<?xml version="1.0" encoding="gb2312" standalone="no"?>

<!DOCTYPE bookinfo [

<!ELEMENT bookinfo (title,author,publish,price)>

<!ELEMENT title (#PCDATA)>

<!ELEMENT author (#PCDATA)>

<!ELEMENT publish (publisher,ISBN,pubdate)>

<!ELEMENT publisher (#PCDATA)>

<!ELEMENT ISBN (#PCDATA)>

<!ELEMENT pubdate (#PCDATA)>

<!ELEMENT price (#PCDATA)>

<!ENTITY pub SYSTEM "code4_14out.xml">

]>

<bookinfo>

<title>计算机导论</title>

<author>丁跃潮等</author>

&pub;

<price>19.7</price>

</bookinfo>

在引用外部一般实体时,有以下几方面需注意。

(1) 因为在一个文档中需引用某些外部文件,所以该文档声明中的standalone 属性不再

是默认值yes,而应该为no 。

(2) 作为外部一般实体的文档,若使用的是XML 的默认字符集即UTF-8 或UNICODE,

则可以在文档头部不进行XML  声明,否则,必须有XML  声明,且声明时,一定要说明

ecoding 属性。

例子3:

myentity.txt:

<?xml version="1.0" encoding="gb2312"?>

这是一个外部实体

<外部实体>内容</外部实体>

外部实体通常用于代替更多文字。

outerentity.dtd:

<?xml version="1.0" encoding="GB2312"?>

<!ELEMENT 书名 (#PCDATA | 外部实体)*>

<!ELEMENT 外部实体 (#PCDATA)>

<!-- 定义一个外部实体 -->

<!ENTITY outer SYSTEM "myentity.txt">

<!-- 定义了书名的islast属性 -->

<!ATTLIST 书名 islast (yes|no|true|false) #REQUIRED>

outerentity.xml:

<?xml version="1.0" encoding="GB2312"?>

<!DOCTYPE 书名 SYSTEM

"outerentity.dtd">

<书名 islast="no">&outer;</书名>

 

定义参数实体

参数实体只能在DTD中使用

3. 内部参数实体

内部参数实体是指在独立的外部DTD 文档的内部定义和使用的实体,其内容为仅能为

DTD 而非XML 文档内容的书写文本。这里提到参数实体与前面所讲的一般实体是有区

别的:

(1) 在引用形式上,一般实体的引用为“&Eentity_name;”,而参数实体的引用则为

“%Eentity_name;”

(2) 在引用范围上,一般实体可在XML 文档中引用,也可在DTD  中引用,而参数实

体只可在DTD 中引用。

定义内部参数实体的语法格式如下:

<!ENTITY % 实体名 "实体值" >

使用:

%实体名

例1. 内部参数实体的使用,代码如源程序code4_15.dtd 所示。

<?xml version="1.0" encoding="gb2312" ?>

<!ELEMENT bookinfo (title,author,publish,price)>

<!ELEMENT title (#PCDATA)>

<!ELEMENT author (#PCDATA)>

<!ENTITY % pub "(publisher,ISBN,pubdate)">

<!ELEMENT publish %pub;>

<!ELEMENT publisher (#PCDATA)>

<!ELEMENT ISBN (#PCDATA)>

<!ELEMENT pubdate (#PCDATA)>

<!ELEMENT price (#PCDATA)>

例子2:

<?xml version="1.0" encoding="GB2312"?>

<!-- 下面先定义了四个元素 -->

<!ELEMENT 书籍列表 (疯狂Java图书)*>

<!ELEMENT 疯狂Java图书 (书名, 介绍)>

<!ELEMENT 书名 (#PCDATA)>

<!ELEMENT 介绍 (#PCDATA)>

<!-- 定义参数实体 -->

<!ENTITY % boolean "yes|no|true|false">

<!-- 定义了书名的islast属性 -->

<!ATTLIST 书名 islast (%boolean;) #REQUIRED>

<!-- 定义了2个实体 -->

<!ENTITY java "疯狂Java讲义">

<!ENTITY jee "轻量级Java EE企业应用实战">

注意:如果需要在DTD中使用参数实体,参数实体必须前向定义。如果颠倒了顺序,将会出错。

    4. 外部参数实体

外部参数实体是指在独立的外部DTD 文档的外部定义和使用的实体,外部参数实体用

于将多个独立的DTD 文档组合成一个大的DTD 文档。定义外部参数实体的语法格式如下:

<!ENTITY % 实体名 SYSTEM|PUBLIC ["公用实体标识名"] ”实体值所在文件的URI“ >

例 外部参数实体的使用,代码如下。

 

<?xml version="1.0" encoding="gb2312"?>

<!DOCTYPE bookinfo SYSTEM "code4_16_1.dtd">

<bookinfo>

<title>计算机导论</title>

<author>丁跃潮等</author>

<publish>

<publisher>高等教育出版社</publisher>

<ISBN>7-04-014768-8</ISBN>

<pubdate>2004.6</pubdate>

</publish>

<price>19.7</price>

</bookinfo>

程序code4_16_1.dtd 为

 

<?xml version="1.0" encoding="gb2312"?>

<!ELEMENT bookinfo (title,author,publish,price)>

<!ELEMENT title (#PCDATA)>

<!ELEMENT author (#PCDATA)>

<!ENTITY % pub SYSTEM "code4_16_2.dtd">

%pub;

<!ELEMENT price (#PCDATA)>

程序code4_16_2.dtd 为

 

<?xml version="1.0" encoding="gb2312" ?>

<!ELEMENT publish (publisher,ISBN,pubdate)>

<!ELEMENT publisher (#PCDATA)>

<!ELEMENT ISBN (#PCDATA)>

<!ELEMENT pubdate (#PCDATA)>

定义符号

​xml不能处理如图片,声音等数据,因此需要定义符号来标识这些数据,让指定的程序处理这些数据。

定义符号的两种语法格式:

定义普通符号的语法格式:

<!NOTATION notation SYSTEM "value">

定义公共符号的语法格式:

<!NOTATION notation PUBLIC "name" "value">

未解析实体

前面介绍了外部实体,就是专门定义一个外部文件来保存实体的值。该外部文件必须满足如下两个要求:

  • 该外部文件是一个文本文件。
  • 该外部文件是满足XML要求的结构化文档。

如果不满足上述两个 要求,xml就无法解析里面的内容,这时只能将外部实体声明为未解析实体。

由于xml解析器不能处理未解析实体所对应的数据,因此xml文档不能像引用普通实体一样直接引用未解析实体,而需要通过ENTITY,ENTITIES类型的属性来调用。

定义未解析实体的语法格式如下:

<!ENTITY % 实体名 SYSTEM|PUBLIC ["公用实体标识名"] "实体值所在文件的uri" NDATA notation>

由上述语法格式看出,定义未解析实体只要在<!ENTITY...>定义后增加 NDATA 和符号名即可。下面的DTD中定义了2个符号和1个未解析实体。

notation.dtd:

<?xml version="1.0" encoding="gb2312"?>

<!-- 下面定义了2个符号 -->

<!NOTATION wmv SYSTEM "video/x-ms-wmv">

<!NOTATION pdf PUBLIC "PDF" "e:/tools/Foxit Reader.exe">

<!-- 只有外部实体才能是未解析实体 -->

<!ENTITY movie SYSTEM "http://www.crazyit.org/test.wmv" NDATA wmv>

<!ELEMENT book (#PCDATA)>

 ​ENTITY 和 ENTITIES类型的属性

​定义ENTITY 或ENTITIES类型的属性与定义其他类型的属性没有太大的区别,只是在xml文档中使用这些属性时,其值只能是未解析实体。

entity.dtd:

<?xml version="1.0" encoding="gb2312"?>

<!-- 下面定义了2个符号 -->

<!NOTATION wmv SYSTEM "video/x-ms-wmv">

<!NOTATION pdf PUBLIC "PDF" "e:/tools/Foxit Reader.exe">

<!-- 定义一个未解析外部实体,该实体对应于wmv符号 -->

<!ENTITY desc_movie SYSTEM "http://www.crazyit.org/test.wmv" NDATA wmv>

<!-- 下面定义3个未解析外部实体,它们都对应于pdf符号 -->

<!ENTITY book_part1 SYSTEM "http://www.crazyit.org/part1.pdf" NDATA pdf>

<!ENTITY book_part2 SYSTEM "http://www.crazyit.org/part2.pdf" NDATA pdf>

<!ENTITY book_part3 SYSTEM "http://www.crazyit.org/part3.pdf" NDATA pdf>

<!ELEMENT book (#PCDATA)>

<!-- 定义2个属性,它们的类型分别是ENTITY和ENTITIES -->

<!ATTLIST book description ENTITY "desc_movie">

<!ATTLIST book content ENTITIES #IMPLIED >

一旦声明某个属性的类型是ENTITY或ENTITIES,意味着该属性值只能是一个或多个未解析实体,而不能是已解析实体。

NOTATION 类型的属性

NOTATION 类型的属性的属性值只能是符号名,而且定义NOTATION类型的属性时必须采用枚举方法列出该属性所支持的值,其语法格式如下:

<!ATTLIST 属性所属的元素 属性名 NOTATION (值1|值2) 约束 默认值>

实例:

<?xml version="1.0" encoding="gb2312"?>

<!DOCTYPE book [

<!ELEMENT book (#PCDATA)>

<!-- 下面定义了2个NOTATION -->

<!NOTATION wmv SYSTEM "video/x-ms-wmv">

<!NOTATION pdf PUBLIC "PDF" "e:/tools/Foxit Reader.exe">

<!-- 定义一个type属性,该属性是NOTATION类型 -->

<!ATTLIST book type NOTATION (pdf|wmv) #FIXED "pdf">

]>

<book type="pdf"/>

转载请注明:大步's Blog » XML笔记2——DTD详解

SiteMap