在XML中使用DTD

DTD介绍

  • DTD( Document Type Definition)文档类型定义。在XML标准中,描述了如何创建DTD,以及如何将它与根据它的规则所编写的XML文档相关联,并且还定义了XML处理器应该如何对DTD进行处理,有了DTD就可以检测XML文档的结构是否正确。
  • DTD在实际应用中的作用主要包括:
    • 可以验证XML文档数据的有效性
    • 可以为某类XML文档提供统一的格式和相同的结构
    • 可以保证在一定范围内,XML文档数据的交流和共享
    • 一个程序设计人员根据DTD就能够知道对应的XML文档逻辑结构,从而编写出相应的处理应用程序
  • 第一个DTD例子:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE 根元素名称 [
	<!ELEMENT 根元素名称(第一个子元素, 第二个子元素)>
	<!ELEMENT 第一个子元素(#PCDATA)>
	<!ELEMENT 第二个子元素(#PCDATA)>
	<!ATTLIST 第一个子元素 属性一 CDATA #REQUIRED>
]>
<根元素名称>
	<第一个子元素 属性一="任意内容">
		文本内容1
	</第一个子元素>
	<第二个子元素>
		文本内容1
	</第二个子元素>
</根元素名称>

DTD的基本语法

  1. DTD内部可以包含下列语句:
  • 元素类型声明语句<!ELEMENT ......>
  • 属性列表声明语句<!ATTLIST ......>
  • 实体声明语句<!ENTITY .......>
  • 符号声明语句<!NOTATION ......>
  • 注释语句
  1. 一个DTA即可以是独立的文档,该文档的扩展名为.dtd。DTD也可以存在于文档内部,如果存在于XML文档内部,则DTD的内容放置于
  2. 例如:demodtd.dtd如下:
<?xml version="1.0" encoding="UTF-8" ?>
<!-- root元素中包含了两个子元素 --!>
<!ELEMENT root (sub1, sub2)>
<!ELEMENT sub1(#PCDATA)>
<!ELEMENT sub2(#PCDATA)>
<!ATTLIST root param1 NOTATION(Jpeg | Png) # REQUIRED
				param2 CDATA # IMPLIED>
<!ENTITY NAME "ENTITY VALUE">
<!NOTATION Jpeg SYSTEM "Image/jpeg">
<!NOTATION Png SYSTEM "Image/png">

引入在XML文档中,代码如下:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYE root SYSTEM "demodtd.dtd">
<root param1 = "Jpeg">
<sub1>&NAME;</sub1>
<sub2>any word </sub2>
</root>

直接内置于XML文档中时,代码如下:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE root[
<!--root元素中包含了2个子元素-->
<!ELEMENT root (sub1,sub2)>
<!ELEMENT sub1 (#PCDATA)>
<!ELEMENT sub2 (#PCDATA)>
<!ATTLIST root param1 CDATA #REQUIRED
			   param2 CDATA #IMPLIED>
<!ENTITY NAME1 "ENTITY VALUE">
<!ENTITY PIC SYSTEM "Sunset.jpg" NDATA jpr>
<!NOTATION jpr SYSTEM "mspaint.exe">
]>
<root param1="PIC">
	<sub1>&NAME1;</sub1>
	<sub2>any word</sub2>
</root>

引入DTD的方式

  1. 外部DTD
    外部DTD的引用须事先已有一个dtd文件,将DTD的约束写到文件中,然后在XML文档中按以下语法格式添加:
    <!DOCTYPE (根元素名称) SYSTEM "外部DTD的URL地址">
    SYSTEM关键字表示文档使用的是私有DTD文件,“外部DTD文件的URI”可以是相对URI或者绝对URI,相对URI是相对于文档类型声明所在文档的位置。“外部DTD文件的URI”这部分也被称为系统标识符(system identifier).
  2. 内部DTD
    使用DTD的最简单的方式,内部DTD就是指将语义约束与XML文档的内容放在同一个XML文档中。紧跟在XML声明和处理指令之后,以<!DOCTYPE[开始,以]>结束语法格式如下:
    <!DOCTYPE 根元素名称 [ 元素描述 ]>
  3. 公用DTD
    公用DTD与外部DTD类似,但是该DTD引用公用的DTD的语法格式如下:
    <!DOCTYPE (根元素名称) PUBLIC "DTD的标识名" "公用DTD的URL地址">
    公共DTD名称要遵循一些约定。如果一项DTD是ISO标准,它的名字要以字符串“ISO”开始,如果是一个非ISO的标准组织批准的DTD,它的名字以“+”开始。如果不是标准组织批准的DTD,它的名字以连字符“-”开始。这些开始字符或字符串后面接//和DTD所有者的名字,之后是另一个双斜杠和DTD描述的文档类型,接着又是一个双斜杠后接ISO 639语言标识符,如EN表示英语,ZH表示中文。
    例如:
  • 自定义的dtd
    //tanglin //DTD STUDENT1.0/ZH
    <!DOCTYPE HR PUBLIC "//tanglin //DTD STUDENT1.0/ZH " "http://city.dlut.edu.cn/xml/dtds/students.dtd">

  • HTML网页的文档类型声明
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

DTD中的元素

  1. 元素定义语法
    语法如下所示:
    <!ELEMENT 元素名 元素类型描述>
    语法详细说明:
  • 元素名:即文档中元素的名称。
  • 元素类型描述:元素类型描述用于指定元素本身是否为对空元素,如果不为空元素元素的内容包括哪些。
  1. 元素类型
    元素类型具体包括以下5类:
  • 字符串类型:即#PCDATA,表示该元素的内容只能是字符串。

  • 空元素:EMPTY,表示该元素只能是空元素。

  • 包含子元素:表示该元素内部嵌套其它元素,具体包含子元素可能有:有序子元素、无序互斥子元素、无序组合子元素。子元素出现的次数也会根据实际的定义而不同。

  • 混合类型:即内容中即包括字符串类型又包括子元素,但混合类型在实际应用中不建议使用。

  • 任意类型:即ANY,表示该标记对于元素内容没有限制,该标记的内容可以是字符串类型、也可以包含子元素、即包含字符串又包括自元素的混合类型、该标记也可以是空元素。在实际应用中尽量避免。

  • 子元素如下:

  1. 有序子元素
    用逗号分隔,表示子元素的出现顺序必须与声明时一致,并且不能被省略。
  2. 无序互斥子元素
    用竖线(|)分隔,表示任选其一,即多个子元素在文档定义中只能出现一个。
  3. 无序组合子元素
    子元素出现频率可以根据不同的符号进行设定这些符号的含义如表2-2所示:
    子元素出现频率符号及其含义
    修饰符 含义
    + 一次或多次
    ? 0次或一次
    * 0次或多次
    缺省 一次
    这些修饰符可以限制元素出现的次数,也可以结合圆括号( )批量设置
  • 混合类型
    混合类型定义的子元素即可以包含字符串又可以包含子元素,其定义方法稍微复杂一些,典型的混合类型定义方法形如<!ELEMENT root (#PCDATA|sub1|sub2)*>。但在实际用该类型使用较少,也不建议使用。
  1. DTD中的属性
    在DTD中声明元素属性的语法:
    <!ATTLIST 元素名称 [属性名 属性类型 [约束] [缺省值]]+>
    在一个ATTLIST 中可以定义同一个元素下的一个或多个属性。如果包含多个属性声明,属性声明之间使用空格间隔。
  • 元素名称:属性所属的元素名称
  • 属性名:属性名称
  • 属性类型:属性的值类型,
  • 约束:元素对属性的约束
修饰符 含义
#REQUIRED 表示该属性是必需的,不能没有
#IMPLIED 表示该属性可以有也可以没有
#FIXED 表示在XML文档中只会给出一个元素属性所定义的固定值。只有当约束为该值时,才能给出缺省值,注意缺省值必须给出
  • 定义示例:
<? xml version="1.0" encoding="UTF-8"?>
<! DOCTYPE root[
<!ELEMENT root (#PCDATA)>
<!ATTLIST root reqParam CDATA #REQUIRED>
<!ATTLIST root impParam CDATA #IMPLIED
			fixParam CDATA #FIXED "default value">
]>
<root reqParam = "required value">
</root>

属性类型

  1. DTD中的ENTITY实体
  • ENTITY 实体,在一个甚至多个XML文档中频繁使用某一条数据,我们可以预先定义一个这条数据的“别名”,即一个ENTITY,然后在这些文档中需要该数据的地方调用它。
  • 实体分类关系图
    实体分类关系图
    1. 通用内部解析实体
      内部实体是最简单的一种实体,该实体的内容为字符串的文本内容。所有的内部实体都是解析实体。内部实体的语法格式如下:<!ENTITY 实体名称 "实体内容"> 例如:
      <!ENTITY one "one">
      <!ENTITY two "&one; I am two">

      • 实体名称:实体名称由DTD程序员自己定义,但必须满足唯一性,即不能重名。同时满足XML的命名规范。
      • 实体内容:所需要表达的文本内容。
    2. 通用外部解析实体
      定义外部解析实体的语法如下:
      <!ENTITY 实体名称 SYSTEM|PUBLIC ["公共实体标识符"] "URI/URL">

      • URI/URL:所引用的外部文件的路径地址,被引用的外部文件必须是可以被解析的,扩展名没有限制。
      • 实体为PUBLIC时才会有相应的“公共实体标识符” ,如果为SYSTEM则没有“公共实体标识符”.
        实例如下:
        <?xml version="1.0" encoding="UTF-8"?>
        <!DOCTYPE aa[
        	<!ELEMENT aa (#PCDATA)>
        	<!ELEMENT copyright SYSTEM "outer.txt">
        ]>
        <aa>&copyright; </aa>
        
    3. 通用外部未解析实体:
      <!ENTITY 实体名称 SYSTEM “URL/URL” NDATA 标记名>
      URI/URL:所引用的外部文件的路径地址
      标记名:被定义的符号的名称。
      实例代码:
      <!ENTITY PICTURE SYSTEM 'pic.jpg' NDATA msp>

    4. 参数内部解析实体
      参数实体和普通实体只能在XML文档中引用,如果需要在DTD中使用实体则必须使用参数实体
      声明参数内部解析实体的语法:
      <!ENTITY % 参数实体名称 "实体内容">
      参数实体名称:实体名称由DTD程序员自己定义,但必须满足唯一性,即不能重名。同时满足XML的命名规范。
      实体内容:所需要表达的文本内容。

    5. 参数外部解析实体
      声明参数外部解析实体的语法:
      <!ENTITY % 参数实体名称 SYSTEM “URL/URL”>
      URI/URL:所引用的外部文件的路径地址
      引用参数实体的语法:
      %参数实体名称;

  1. DTD符号
    普通符号的语法格式:
    <!NOTATION 符号名称 SYSTEM | PUBLIC ["公共符号标识符"] "URI\URL">
  • 符号名称:名称由DTD程序员自己定义,但必须满足唯一性,即不能重名。同时满足XML的命名规范
  • URI\URL:外部来处理这些未解析数据的程序路径
  • 符号为PUBLIC时才会有相应的“公共符号标识符” ,如果为SYSTEM则没有“公共符号标识符”

DTD定义格式缺点

  • DTD本身是基于正则表达式的,描述能力相对较弱。
  • DTD不支持数据类型,对数据的约束不够准确。
  • DTD约束能力不足,无法对语义作出更精细的语义限制。
  • DTD的结构不够好,可重用性较差。

猜你喜欢

转载自blog.csdn.net/WilliamChancwl/article/details/85180277