XML学习笔记2

DTD

DTD是什么?

文档类型定义(Document Type Definition)是一套为了进行程序间的数据交换而建立的关于标记符的语法规则。它是标准通用标记语言和可扩展标记语言1.0版规格的一部分,文档可根据某种DTD语法规则验证格式是否符合此规则。

产生的背景

XML基本语法允许用户随意创建自己的标记,添加元素和属性等,但如果大家都按自己的意愿这么做,产生的XML文档也就失去了共享、交换、理解的价值。因此必须制定一套规则来规范XML文档标记的结构。这就是DTD。

DTD声明的格式

<!DOCTYPE root_node[<!--DTD定义的内容-->]>

三种使用方式

  • 直接内装式
  • 外部文件式
  • 混合式
内装DTD

内装DTD的语法与示例
 <?xml version=“1.0” endcoding=“GB2312” standalone=“yes”?>
<!DOCTYPE 持股信息[
<!ELEMENT 持股信息(股东)* >
<!ELEMENT 股东(姓名,浦发银行,华夏基金)>
<!ELEMENT 姓名(#PCDATA)>
<!ELEMENT 浦发银行(#PCDATA)>
<!ELEMENT 华夏基金(#PCDATA)>
]>
<持股信息>
<股东>
<姓名>张志强</姓名>….

外部文件式

外部文档式的示例:
用文本编辑工具建立文件“char01.dtd”,内容如下:

<?xml version="1.0" encoding="utf-8"?>
  <!ELEMENT 持股信息(股东)* >
  <!ELEMENT 股东(姓名,浦发银行,华夏基金)>
  <!ELEMENT 姓名(#PCDATA)>
  <!ELEMENT 浦发银行(#PCDATA)>
  <!ELEMENT 华夏基金(#PCDATA)> 

使用外部文档,在XML中要添加以下声明:
<!DOCTYPE 持股信息 SYSTEM "char01.dtd" >

上述格式中SYSTEM代表此DTD文件由私人制定,假如是国际标准则要用PUBLIC,例如Struts的XML配置:

<!DOCTYPE struts PUBLIC
        "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
        "http://struts.apache.org/dtds/struts-2.0.dtd">

DTD元素

元素声明

基本格式
<!ELEMENT 元素名 元素内容模式>
空模式(关键字EMPTY
<!ELEMENT image(EMPTY)>
在相应的XML文档中对应为:<image/>
任意模式 (关键字ANY):与ANY相对应的元素内容没有任何定义和限制。应注意:ANY类型的元素,其包含的子元素并不能继承父元素的模式类型。ANY的使用将导致XML文档结构的丧失,通常只在创建文档的初期使用。例如,一份描述图书信息的DTD设计
<?xml version=“1.0” endcoding=“GB2312” ?>
<!ELEMENT booklist(book?)>
<!ELEMENT book ANY>
<!ELEMENT author(#PCDATA)>
<!ELEMENT title(#PCDATA)>

混合模式:没有关键字,语法格式:
<!ELEMENT 父元素名(#PCDATA|子元素1|子元素2|…)*>
注意:
1、#PCDATA是指该混合元素的父元素内容可以是字符串,长度不限,但要交XML解析器处理。
2、子元素之间的“|”符号与后面的“*”符号一起表示这些子元素出现的次数与顺序都不受限制
示例:

<!ELEMENT music (#PCDATA | name | singer)* >

另外,附加一些符号说明

符号含义
+子元素至少要出现一次
*子元素可出现任意次,包括不出现
?子元素出现零次或一次
?子元素有多种选择,但只可以选择其一

DTD定义的完整性

(1)不允许无穷嵌套,例如:
<!ELEMENT 商品名称(name,price)>
<!ELEMENT price(商品名称,unit)>
 (2)XML文件中的每个标记都必须在DTD中有相应元素进行约束,且必须最终约束数据类型为#PCDATA。
例如:<!ELEMENT 列车时刻表(T28,T29)>
<!ELEMENT T28(hour,minute)>
<!ELEMENT T29(hour,minute)>
这样的DTD不完整,因为还没有约束元素 hour 和 minute。

DTD属性

声明格式
!ATTLIST 元素名 属性名 属性类型 属性默认值>

以下为XML属性类型

CDATA文本字符串。解析器不处理。
ID具有唯一性的属性类型,此属性值在整个XML文档中不可重复。
IDREF这是其它元素的ID属性值
IDREFS这是其它元素的ID属性值列表,用空格分隔。
ENTITY为一个实体。
ENTITYS用空格分隔的实体。
NMTOKENName和Token。是一个关键字的名称
NMTOKENS用空格分隔的NMTOKEN
NOTATION参考的标记声明。
Enumerated枚举类型的属性。

属性的默认值只有三种:#REQUIRED、#IMPLIED、#FIXED。
#REQUIRED是非空的意思,只要该属性出现就必须有一个具体的取值。
#IMPLIED表示该属性的值可有可无。
#FIXED表示该属性取用引号括越来的具体值。也有使用竖线分隔的具体值,这时属性值取枚举值。
一些例子:
<!ATTLIST 汽车 车牌 CDATA #REQUIRED>
<!ATTLIST 电动车 车牌 CDATA #IMPLIED>
<!ATTLIST 报警电话 号码 #FIXED“110”>
<!ATTLIST 论文 关键字 NMTOKENS #REQUIRED>
XML文档中对应:<论文 关键字=“Agent 进化 协作”>
<!ATTLIST 姓名 性别(男|女)#REQUIRED>

DTD实体

实体机制允许将不同类型的数据并入XML文档中,可以是一段文本、一块数据,甚至一个文件。这样就可以快速地将经常使用的数据插入到XML文档中任何位置。
实体的作用就是用较短的文本替代较长的文本,实现一处修改,处处修改。
实体必须在DTD中声明后才能在其它地方引用。 实体有许多称呼:通用实体、参数实体、内部实体、外部实体、解析实体、未解析实体。下面分别阐述:
内部实体与XML文档在一起,外部实体则存放在其它文件内,通过URL来关联。
通用实体:在XML文档中引用的实体。以“&”开始,以“;”结束。声明格式:

内部通用实体: <!ENTITY 实体名 实体值>
外部通用实体: <!ENTITY 实体名 SYSTEM URL-URI>

DTD标记符号

XML文档只是一个文本文档,它自身无法包容其它类型的数据(理论上允许通过转换编码方式嵌入),如二进制代码、图片、视频、动画等。XML不处理这些数据,而是采用定义符号的方式标识这些数据,必要时再通过关联外部处理程序交由指定的外部程序去处理。
定义符号用途:1、定义未解析实体;2、作为NOTATION类型的属性值。

声明格式如下:
普通符号:<!NOTATION 符号名称 SYSTEM “value”>  
   公共符号:<!NOTATION 符号名称 PUBLIC “name” “value”> 
   标记符号值通常有两种形式:1、MIME类型;2、外部程序所在路径。
<!NOTATION gif SYSTEMACDSee.exe”>
<!ATTLIST DISPLAY src ENTITY #REQUIRED>

参数实体

这是一种专门用于DTD文件中的实体,在DTD中定义并且只能由DTD文件自身通过实体引用来使用。它以“%”开始,以“;”结束。主要用于简化DTD,方便重用与修改。格式:

 <!ENTITY %实体名 实体值>
 <!ENTITY % HeadingAlign “left|center|right”>
   <!ELEMENT message(Content,Align)+>
   <!ELEMENT Content(#PCDATA)>
   <!ELEMENT Align(%HeadingAlign;)>

第一行说明所创建的参数实体HeadingAlign是用于保留描述对齐方式的字符串,随后再使用对齐方式就只要用对齐元素Align,用%HeadingAlign代替就行了。参数实体也可以采用外部定义方式,但它只存在于DTD内与关联的XML文档无关。例如:

<?xml version=“1.0” encoding=“gh2312”?>
<!ELEMENT name (#PCDATA)>
<!ELEMENT sex EMPTY>
<!ATTLIST sex value (男|女) “男”>

将上述代码保存为importDtd.dtd,下面是引用它的例子:

<?xml version=“1.0” encoding=“gh2312”?>
<!DOCTYPE students[
<!ENTITY % name SYSTEM “importDtd.dtd”>
<!ELEMENT students (student*)>
<!ELEMENT students(name,sex)>
  %name;
]>
<students>
  <student> <name>陈晓</name> <sex /> </student>
</students>

三个样例

1.电视节目表DTD

<!DOCTYPE TVSCHEDULE [ 
<!ELEMENT TVSCHEDULE (CHANNEL+)> 
<!ELEMENT CHANNEL (BANNER,DAY+)> 
<!ELEMENT BANNER (#PCDATA)> 
<!ELEMENT DAY (DATE,(HOLIDAY|PROGRAMSLOT+)+)> 
<!ELEMENT HOLIDAY (#PCDATA)> 
<!ELEMENT DATE (#PCDATA)> 
<!ELEMENT PROGRAMSLOT (TIME,TITLE,DESCRIPTION?)> <!ELEMENT TIME (#PCDATA)> 
<!ELEMENT TITLE (#PCDATA)>  
<!ELEMENT DESCRIPTION (#PCDATA)> 
<!ATTLIST TVSCHEDULE NAME CDATA #REQUIRED>
<!ATTLIST CHANNEL CHAN CDATA #REQUIRED> 
<!ATTLIST PROGRAMSLOT VTR CDATA #IMPLIED> 
<!ATTLIST TITLE RATING CDATA #IMPLIED> 
<!ATTLIST TITLE LANGUAGE CDATA #IMPLIED> 
]> 

2.报纸文章DTD

“`

2.产品目录DTD

 ```
<!DOCTYPE CATALOG [ 
<!ENTITY AUTHOR "John Doe"> 
<!ENTITY COMPANY "JD Power Tools, Inc."> 
<!ENTITY EMAIL "jd@jd-tools.com"> 
<!ELEMENT CATALOG (PRODUCT+)> 
<!ELEMENT PRODUCT (SPECIFICATIONS+,OPTIONS?,PRICE+,NOTES?)> 
<!ATTLIST PRODUCT 
       NAME CDATA #IMPLIED CATEGORY (HandTool|Table|Shop-   
       Professional) "HandTool" 
       PARTNUM CDATA #IMPLIED PLANT  (Pittsburgh|Milwaukee|Chicago) "Chicago" INVENTORY (InStock|Backordered|Discontinued) "InStock"> 
       <!ATTLIST SPECIFICATIONS WEIGHT CDATA #IMPLIED POWER CDATA #IMPLIED> 
<!ELEMENT OPTIONS (#PCDATA)> 
<!ATTLIST OPTIONS 
       FINISH (Metal|Polished|Matte) "Matte" 
       ADAPTER (Included|Optional|NotApplicable) "Included" 
       CASE (HardShell|Soft|NotApplicable) "HardShell"> 
<!ELEMENT PRICE (#PCDATA)> 
<!ATTLIST PRICE MSRP CDATA #IMPLIED WHOLESALE CDATA #IMPLIED STREET CDATA #IMPLIED SHIPPING CDATA #IMPLIED> 
<!ELEMENT NOTES (#PCDATA)> ]> 
<!ELEMENT SPECIFICATIONS (#PCDATA)>

DTD存在的问题:
1、DTD文档采用EBNF语法,相对独立,规则也比较繁琐,其本身不是标记语言,也不符合XML文档标准。
2、DTD的数据类型太简单,元素几乎都声明为#PCDATA,属性类型虽然稍多,但仍缺少常用的整数、日期等。
3、使用DTD的XML文档只能引用一个DTD文件,即DTD不支持命名空间。需要引用多个领域的XML规则时遇到困难。
4、DTD的扩展机制复杂而且较弱,已经不能适应信息环境的不断发展,其功能已显不足。
DTD适用场合:
I、文件是叙述性的,并有混合内容;
II、需要约束标记之间的关系,而非标记本身的内容;
III、需要使用实体;
IV、XML文档的使用者对于使用DTD达成一致。    

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值