XML文件约束之DTD详解以及xml文件的dtd描述文件本地化

1.XML文件约束与DTD的简单介绍

我们编写文档来约束一个XML文档的书写规范,这称之为XML约束。

常用的约束技术有:

  • XML DTD
  • XML Schema

DTD的基本概念:

document type definition 文档类型定义

DTD文件一般和XML文件配合使用,主要是为了约束XML文件。

XML文件引入DTD文件,这样XML可以自定义标签,但又受到DTD文件的约束。比如上一节使用XML描述一个班级的信息,如果我们给每一个学生定义一个<面积>标签,语法上也是没有错误的,但是不符合语义,学生怎么能够用面积来描述呢?这时候我们就需要用到DTD文件来约束这个XML。

 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
<?xml version="1.0" encoding="gb2312"?> <class> stu id="001"> name>杨过</name> sex>男sex> age>20age> 面积>100面积> stu> class>

1.1 DTD约束快速入门案例

基本语法:

  
  
  • 1
    • 1
    !ELEMENT 元素名 类型>

    我们还以班级为例,编写如下DTD文件,myClass.dtd:

      
      
  • 1
  • 2
  • 3
  • 4
  • 5
    • 1
    • 2
    • 3
    • 4
    • 5
    !ELEMENT 班级 (学生+)> !ELEMENT 学生 (名字,年龄,介绍)> !ELEMENT 名字 (#PCDATA)> !ELEMENT 年龄 (#!ELEMENT 介绍 (#PCDATA)>

    第一行表示根元素为班级,并且有学生这个子元素,子元素为1或者多个。
    第二行表示学生的子元素为名字,年龄,介绍
    名字下面没有子元素了,那么#PCDATA表示名字里面可以放任意文本。
    年龄和介绍也是类似。

    编写myClass.xml文件并引入DTD文件如下:

      
      
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    <?xml version="1.0" encoding="utf-8"?> <!--引入dtd文件,约束这个xml--> <!DOCTYPE 班级 SYSTEM "myClass.dtd"> 班级> 学生> 名字>周小星名字> 年龄>23年龄> 介绍>学习刻苦介绍> 学生> 名字>林晓名字> 年龄>25介绍>是一个好学生学生> 班级>

    引入中写的:SYSTEM,表示当前的DTD文件是本地的
    如果写的是PUBLIC,则表示引入的DTD文件是来自于网络的.

    这时候引入的DTD文件是没有产生作用的,如果我们在学生元素中添加子元素<面积>,打开这个XML文件,浏览器依然不会报错。

      
      
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    介绍> 面积>100平米 我们需要编程校验XML文档的正确性

    IE5以上的浏览器内置了XML解析工具:Microsoft.XMLDOM,开发人员可以编写JavaScript代码,利用这个解析工具装载XML文件,并对XML文件进行DTD验证。

    我们编写myXmlTools.html来对这个XML进行校验,如下:

      
      
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    html> head> <!--自己编写一个简单的解析工具,去解析XML DTD是否配套--> script language="javascript"> // 创建xml文档解析器对象 var xmldoc = new ActiveXObject("Microsoft.XMLDOM"); // 开启xml校验 xmldoc.validateOnParse = "true"; // 装载xml文档,即指定校验哪个XML文件 xmldoc.load("myClass.xml"); document.writeln("错误信息:"+xmldoc.parseError.reason+"<br>"); document.writeln("错误行号:"+xmldoc.parseError.line); script> head> body> body> html>

    用IE浏览器打开这个html文件,可以看到运行结果:

    可以看到第9行正是我们添加的<面积>这一行。

    2.DTD细节

    2.1 DTD文档的声明及引用

    1.内部DTD文档

      
      
  • 1
  • <!DOCTYPE 根元素 [定义内容]>

    2.外部DTD文档

    引入外部的DTD文档分为两种:

    (1)当引用的DTD文件是本地文件的时候,用SYSTEM标识,并写上”DTD的文件路径”,如下:

    <!DOCTYPE 根元素 SYSTEM "DTD文件路径">

    (2)如果引用的DTD文件是一个公共的文件时,采用PUBLIC标识,如下方式:

    <!DOCTYPE 根元素 PUBLIC "DTD名称" "DTD文件的URL">

    比如下例:

    <!DOCTYPE web-app PUBLIC "-//Sun Microsystems,Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">

    2.2 DTD基本语法:

    !ELEMENT NAME CONTENT>

    其中:
    - ELEMENT是关键字,是不能修改的
    - NAME表示元素名称
    - CONTENT是元素类型,必须要大写!CONTENT的内容有三种写法:

    (1)EMPTY——表示该元素不能包含子元素和文本,但可以有属性。
    (2)ANY——表示该元素可以包含任何在该DTD中定义的元素内容
    (3)#PCDATA——可以包含任何字符数据,但是不能在其中包含任何子元素

    2.3 DTD元素的组合类型:

    DTD中这样规定:

    !ELEMENT 家庭(人+,家电*)>

    这个DTD规定了家庭元素中可以有1到多个”人”这个子元素,也可以有0到多个”家电”这个子元素。其中的加号”+”和星号”*”的含义与正则表达式中的含义一致。

    XML这样写:

    家庭>
         名字="张晓明" 性别="男" 年龄="25"/>
        "李小钢" 性别="36" 爱好="作个教育家和伟人"/>
        家电 名称="彩电" 数量="3"/>
    家庭>

    关于组合类型,有下述的的修饰符可以使用:

    符号 用途 示例 示例说明
    () 用来给元素分组 (古龙|金庸),(王朔|余杰) 分成两组
    | 在列出的对象中选择一个 (男人|女人) 表示男人或者女人必须出现,两者至少选其一
    + 该对象必须出现一次或者多次 (成员+) 表示成员必须出现,而却可以出现多个成员
    * 该对象允许出现0次或者多次 (爱好*) 爱好可以出现两次到多次
    ? 该对象必须出现0次或者1次 (菜鸟?) 菜鸟可以出现,也可以不出现,如果出现的话,最多只能出现一次
    , 对象必须按指定的顺序出现 (西瓜,苹果,香蕉) 表示西瓜、苹果、香蕉必须出现,并且按这个顺序出现

    2.4 属性定义

    DTD中属性的定义是这样的:

      
      
  • 1
  • 2
  • 3
  • 4
    • 1
    • 2
    • 3
    • 4
    !ATTLIST 元素名称 属性名称 类型 属性特点 属性名称 类型 属性特点...... >

    其中,属性的类型有下面5种:

    (1) CDATA
    (2) ID
    (3) IDREF/IDREFS
    (4) Enumerated
    (5) ENTITY/ENTITIES

    属性的特点有如下4种:

    (1) #REQUIRED,表示这个属性必须给,不给就报错
    (2) #IMPLIED,表示这个属性可以给也可以不给
    (3) #FIXED value,表示这个属性必须给一个固定的value值
    (4) Default value,表示这个属性如果没有值,就分配一个默认的value值

    比如,我们想在学生这个子元素上加上地址这个属性,而且这个属性是必须的,示例如下:

      
      
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    <?xml version="1.0" encoding="utf-8"?> 学生 地址="香港"> "澳门"> 这个时候相应的DTD文件也要更新,不然就会报错,如下:

      
      
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    !ATTLIST 学生 地址 CDATA #REQUIRED > PCDATA)>

    2.4.1 对于属性类型的详细解释

    (1)属性类型-CDATA,表示属性值可以是任何字符(包括中文和数字)

      
      
  • 1
  • 2
  • 3
    • 1
    • 2
    • 3
    !ATTLIST 木偶 姓名 REQUIRED >
    木偶 姓名="匹诺曹"/>
    "PiNuocao"/>
    "123"/>

    (2)属性类型-ID,表明该属性的取值必须是唯一的,但是属性的值不能是以数字开头!

    !ELEMENT 公司职员 ANY>
    !ATTLIST 公司职员 编号 ID #REQUIRED 姓名 REQUIRED >
      
      
  • 1
  • 2
    • 1
    • 2
    公司职员 编号="Z001" 姓名="张三"/> "Z002" 姓名="李思"/>

    (3)属性类型-IDREF/IDREFS
    - IDREF属性的值指向文档中其它地方声明的ID类型的值
    - IDREFS同IDREF,但是可以具有由空格分开的多个引用。

      
      
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    !ELEMENT 家庭(人+)> !ELEMENTEMPTY> !ATTLISTrelID REQUIRED paraentID IDREFS #IMPLIED name REQUIRED >
    relID="P_1" name="爸爸"/>
        "P_2" "妈妈"/>
        "P_3" parentID="P_1 P_2" "儿子"/>
     (4)属性类型-Enumerated,事先定义好一些值,属性的值必须在所列出的值的范围内。

      
      
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    !ATTLIST person 婚姻状态 (single|married|divorced|widowed) #IMPLIED > person 性别 (男|女) #REQUIRED >

    (5)属性类型-ENTITY,实体

    实体定义:
    - 实体用于为一段内容创建一个别名,以后在XML文档中就可以使用别名引用这段内容了。
    - 在DTD定义中,一条!ENTITY语句用于定义一个实体。
    - 实体可分为两种类型:引用实体和参数实体。引用实体是被XML文档应用的,而参数实体是被DTD文件本身应用的。

    ①引用实体:

    • 引用实体主要在XML文档中被应用
      语法格式如下,引用实体的定义内容最好放在DTD文件的最后。
    !ENTITY 实体名称 "实体内容">

    引用方式:&实体名称; 末尾要带上分号,这个引用将直接转变成实体内容

    举例如下:

    !ENTITY copyright "I am a programmer">
    ....
    &copyright;

    ②参数实体:

    参数实体被DTD文件自身使用
    语法格式为:

    !ENTITY % 实体名称 "实体内容">

    引用方式为:%实体名称

    举例:

    !ENTITY % TAG_NAME "姓名|EMAIL|电话|地址">
    
    !ELEMENT 个人信息 (%TAG_NAME;|生日)>
    !ELEMENT 客户信息 (%TAG_NAME;|公司名)>

    3.DTD实际案例

    学习DTD的目标在于:
    (1)要求我们能够看得懂DTD文件,
    (2)我们可以根据给出的DTD写出对应的XML文件

    下面我们看一个案例,下述的DTD文件是从W3School在线教程中的DTD案例中拿过来的,细看每一行,我们都应该能够看得懂。

      
      
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    AUTHOR "John Doe"> COMPANY "JD Power Tools,Inc."> EMAIL "jd@jd-tools.com"> CATALOG (PRODUCT+)> PRODUCT (SPECIFICATIONS+,102);">OPTIONS?,102);">PRICE+,102);">NOTES?)> PRODUCT CATEGORY (HandTool|Table|Shop-Professional) "HandTool" PARTNUM PLANT (Pittsburgh|Milwaukee|Chicago) "Chicago" INVENTORY (InStock|Backordered|Discontinued) "InStock"> SPECIFICATIONS (#SPECIFICATIONS WEIGHT POWER IMPLIED> OPTIONS (#OPTIONS FINISH (Metal|Polished|Matte) "Matte" ADAPTER (Included|Optional|NotApplicable) "Included" CASE (HardShell|Soft|HardShell"> PRICE (#PRICE MSRP WHOLESALE STREET SHIPPING NOTES (# 然后我们可以根据该DTD编写如下最简单的XML文件:

      
      
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
    • <!DOCTYPE CATALOG SYSTEM "product.dtd"> CATALOG> PRODUCT NAME="康帅傅矿泉水" CATEGORY="Table" PARTNUM="12" PLANT="Chicago"> SPECIFICATIONS WEIGHT="20" POWER="18">这里是细节SPECIFICATIONS> PRICE>25PRICE> PRICE>28PRICE> PRODUCT> CATALOG>

    然后我们用Microsoft.XMLDOM校验该XML,会发现没有任何错误。但是要注意编码。

    版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

    相关推荐


    php输出xml格式字符串
    J2ME Mobile 3D入门教程系列文章之一
    XML轻松学习手册
    XML入门的常见问题(一)
    XML入门的常见问题(三)
    XML轻松学习手册(2)XML概念
    xml文件介绍及使用
    xml编程(一)-xml语法
    XML文件结构和基本语法
    第2章 包装类
    XML入门的常见问题(二)
    Java对象的强、软、弱和虚引用
    JS解析XML文件和XML字符串详解
    java中枚举的详细使用介绍
    了解Xml格式
    XML入门的常见问题(四)
    深入SQLite多线程的使用总结详解
    PlayFramework完整实现一个APP(一)
    XML和YAML的使用方法
    XML轻松学习总节篇