在上一篇笔记中,将文档类型分类时,曾经根据文档是否使用并遵守了dtd或schema来区分为格式良好的xml和有效的xml,那么什么是dtd和schema呢?dtd和schema都是用来规范xml文档的,对xml文档进行语义约束的,dtd简单易用,schema则功能强大。在这篇笔记中,首先学习一下dtd(document type definition,文档类型定义)。
  1、在xml文档中怎么使用dtd
  导入方式     语法格式     说明    
内部dtd                
将dtd定义放在xml文档内部,紧跟在xml声明和处理指令后面
 如:
外部dtd                
将dtd单独定义在一个文件内,然后通过关键字system导入dtd
 如:
公用dtd                
公用dtd,这种dtd一般是由某个权威机构指定,供特定行业或公众使用,通过关键字public导入
 如:
2、 dtd的结构
  dtd文档本身不是xml文档,而只是为xml定义语义约束的文档,dtd文档的语法非常简单,大致有如下结构:
  (1)第一行是dtd文档的声明,语法和xml的声明相同
  (2)0到多个注释部分,dtd注释与xml注释语法相同
  (3)0到多个定义,每个定义一个xml元素
  (4)0到多个定义,每个为xml元素定义一个属性
  (5)0到多个定义,每个定义一个实体
  (6)0到多个定义,每个定义一个符号
  其中、、、4个定义彼此完全独立,无须互相嵌套,下面就逐一说明这四种定义。
  3、定义元素
  (1)元素类型定义,element type definition,简称etd
  (2) 元素类型
          元素类型     定义格式     说明    
       任意类型          元素可以是字符串,可以是空元素,也可以包含子元素    
       字符串值          元素值只能是字符串,不可以是空元素,也不能包含子元素    
       空元素               
       包含子元素           比较复杂,需要详细定义子元素之间的顺序以及子元素出现的次数等    
       混合类型          指定值只能是几个确定的类型,比任意类型有更强的约束,但功能相当,应尽量使用混合类型
关于混合类型的定义,说明几点:
  a:#pcdata必须放在最前面
  b:#pcdata和各子元素之间只能用竖线(|)分隔,不要使用逗号分隔
  c:不要在子元素之后使用?、*、+等表示频率的修饰符
  (3)定义子元素
          定义子元素的语法     说明     子元素的出现频率修饰词     说明    
       (子元素1,子元素2,...)     使用英文逗号定义有序的子元素     默认(没有修饰词)     出现一次,且只能出现一次    
       (子元素1|子元素2|...)     使用竖线定义互斥的子元素     ?     出现0或1次    
       ((子元素1,子元素2)|(子元素3,子元素4))     使用括号将子元素分组     +     出现1或多次    
       (子元素1|子元素2|...)+     使用竖线互斥,然后使用频率修饰实现定义无序的子元素     *     出现0或多次
4、定义属性
  在xml中,属性不能单独存在,因此定义属性时必须指定属于哪个元素。定义属性的语法格式如下:
     
(1)属性类型
          类型     说明    
       cdata     该属性值只能是字符串数据    
       (en1|en2|en3)     该属性值必须是一系列枚举值之一    
       id     该属性值必须是有些的标识符,且该属性值可用于标识该元素,因此必须在此xml文档中唯一    
       idref     该属性值必须是引用另一个已有的id类型的属性值    
       idrefs     该属性值必须是引用已有的一个或多个id类型的属性值,多个id类型的属性值之间使用空格分隔    
       nmtoken     该属性值必须是合法的xml名称,必须是字符串数据,比cdata约束更强,只能由字母、数字、下划线、中划线,点号和冒号组成    
       nmtokens     该属性值必须是一个或多个nmtoken类型的属性值,多个使用空格分隔    
       entity     该属性值是一个外部实体,比如图片    
       entities     该属性值是一个或多个entity类型的属性值,多个使用空格分隔    
       notation     该属性值是在dtd中声明过的符号(notation),这是个将要过期的规范,尽量避免使用    
       xml:     该属性值是一个预定义的xml值
(2)元素对属性的约束与默认值的关系
          元素对属性的约束     说明     默认值    
       未指定           必须指定默认值    
       #required     必须的属性,必须为相应元素提供该属性     不能指定默认值    
       #implied     该属性可有可无     不能指定默认值    
       #fixed     该属性值是固定的,定义时必须指定固定值     必须指定默认值
5、定义实体
  实体引用就是用一个字符串代替另一个字符串,类似于c语言中的宏,上一篇笔记中已经提到过xml中内置的5个实体引用,在这里接着看看怎么自定义实体引用。
          实体类型     使用场所     定义语法     使用语法     说明    
       普通实体     xml          &实体名;          
       参数实体     dtd          %实体名;     必须在使用前先定义    
       外部实体     xml          &实体名;     这里外部文件必须是满足xml文档结构的文本文档    
       公用外部实体     xml          &实体名;          
       外部参数实体     dtd          %实体名;          
       公用外部参数实体     dtd          %实体名;          
       未解析实体     xml          需要通过entity等类型的属性调用     未解析实体不能由xml文档解析,而需要根据相应的符号名去解析    
       公用未解析实体     xml
6、定义符号
  定义符号也有两种语法格式,分别定义普通符号和公用符号:
          符号类型     定义语法    
       普通符号         
       公用符号
符号值通常有两种形式:
  (1)mime:通用mime类型的文件总是由相应的程序负责处理
  (2)外部程序所在路径:直接指定某个外部程序负责处理xml文档中的外部数据
  符号通常有两种用途:
  (1)如上,符号可以用来定义未解析实体
  (2)符号可以作为entity或entities类型的属性值
  (3)符号还可以作为notation类型的属性的值,定义notation类型的属性时,语法如下:
     
比一般的属性定义多一个值的列表。
   
 
   