使用dtd制作XML约束

目前主流的XML模式有XML DTD和XML Schema,他们都是用来规定XML的约束的,本文主要讲解DTD(文档类型定义),不会涉及到Schema,从何处开始了解DTD呢,为了便捷直观,我们先直接拿出一份导入了DTD文件的XML配置样例给大家看看,下面的是mybatis3框架的主配置XML文件,这里只配置了部分选项。

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <properties resource="config.properties"></properties>

    <typeAliases>
        <typeAlias alias="User" type="me.poplaris.mybatis.bean.User"/>
    </typeAliases>

    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="${driver}"/>
                <property name="url" value="${url}"/>
                <property name="username" value="${username}"/>
                <property name="password" value="${password}"/>
            </dataSource>
        </environment>
    </environments>

    <mappers>
        <mapper resource="mybatis/User.xml"/>
    </mappers>
</configuration>
我们仔细来看看这个XML文件,首先<!DOCTYPE>声明标签

<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
这实际上为当前的XML文件引入了DTD约束,大家可以按照下面方式来解读

<!DOCTYPE 根元素 元素声明>
上面configuration即是根元素,一个XML文件只能有一个根元素,后面紧跟的即为该元素的详细声明,PUBLIC表示引入的DTD文件为外部共享文件, "-//mybatis.org//DTD Config 3.0//EN" 表示引入的DTD文件的逻辑名称, "http://mybatis.org/dtd/mybatis-3-config.dtd" 表示引入的DTD文件的URL,即一个完整的引入外部共享DTD的声明方式应该是如下:

<!DOCTYPE 根元素 PUBLIC "DTD文件逻辑名称" "DTD文件URL">如果你引入的是一个私有的本地的DTD文件(自己创建没有公开发行),那么声明方式如下:

<!DOCTYPE 根元素 SYSTEM "DTD文件URL">声明引入DTD已经完成,接下来该是根据DTD的约束来制定相应的配置了,那么在这个XML配置中都规定了哪些配置呢,我们可以通过IDE的内容辅助来详细查看


根元素下的这些子元素配置都是怎么规定的呢,自然是在DTD文件中做约束的,我们详细看看mybatis-3-config.dtd文件

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

<!ELEMENT configuration (properties?,settings?,typeAliases?,typeHandlers?,objectFactory?,objectWrapperFactory?,plugins?,environments?,databaseIdProvider?,mappers?)>

<!ELEMENT databaseIdProvider (property*)>
<!ATTLIST databaseIdProvider
type CDATA #REQUIRED
>

<!ELEMENT properties (property*)>
<!ATTLIST properties
resource CDATA #IMPLIED
url CDATA #IMPLIED
>

<!ELEMENT property EMPTY>
<!ATTLIST property
name CDATA #REQUIRED
value CDATA #REQUIRED
>

<!ELEMENT settings (setting+)>

<!ELEMENT setting EMPTY>
<!ATTLIST setting
name CDATA #REQUIRED
value CDATA #REQUIRED
>

<!ELEMENT typeAliases (typeAlias*,package*)>

<!ELEMENT typeAlias EMPTY>
<!ATTLIST typeAlias
type CDATA #REQUIRED
alias CDATA #IMPLIED
>

<!ELEMENT typeHandlers (typeHandler*,package*)>

<!ELEMENT typeHandler EMPTY>
<!ATTLIST typeHandler
javaType CDATA #IMPLIED
jdbcType CDATA #IMPLIED
handler CDATA #REQUIRED
>

<!ELEMENT objectFactory (property*)>
<!ATTLIST objectFactory
type CDATA #REQUIRED
>

<!ELEMENT objectWrapperFactory (property*)>
<!ATTLIST objectWrapperFactory
type CDATA #REQUIRED
>

<!ELEMENT plugins (plugin+)>

<!ELEMENT plugin (property*)>
<!ATTLIST plugin
interceptor CDATA #REQUIRED
>

<!ELEMENT environments (environment+)>
<!ATTLIST environments
default CDATA #REQUIRED
>

<!ELEMENT environment (transactionManager,dataSource)>
<!ATTLIST environment
id CDATA #REQUIRED
>

<!ELEMENT transactionManager (property*)>
<!ATTLIST transactionManager
type CDATA #REQUIRED
>

<!ELEMENT dataSource (property*)>
<!ATTLIST dataSource
type CDATA #REQUIRED
>

<!ELEMENT mappers (mapper*,package*)>

<!ELEMENT mapper EMPTY>
<!ATTLIST mapper
resource CDATA #IMPLIED
url CDATA #IMPLIED
class CDATA #IMPLIED
>

<!ELEMENT package EMPTY>
<!ATTLIST package
name CDATA #REQUIRED
>
大家看很多 <!ELEMENT> 标签,这是DTD的元素设定标签,它的语法为

<!ELEMENT 元素名称 元素内容>
我们以mybatis-3-config.dtd文件里最先开始的 标签为例

<!ELEMENT configuration (properties?,mappers?)>
它定义了一个名叫configuration的的元素,后面()内表述的是这个元素的子元素声明,即

<!ELEMENT 元素名称 (子元素1?,子元素2?,子元素3?,...子元素n?)>

从上面我们可以看出这个configuration元素可以包含的子元素有下面几个,同时注意的是这些元素在XML中出现的顺序也是根据定义的顺序如下

properties settings typeAliases typeHandlers objectFactory objectWrapperFactory plugins environments databaseIdProvider mappers

 
 

如果你在设置元素的时候没有按照DTD文件约束的顺序,那么IDE将会显示错误

Thecontentofelementtype"configuration"mustmatch"(properties?,mappers?)"
只知道了configuration都有哪些子元素以及子元素出现的顺序,那么每个子元素后面紧跟的问号又表示什么呢,它有点类似正则的功能,表示这些子元素出现的次数,在这里他们表示这些子元素最多出现一次,类似的声明方式还有

<!ELEMENT 元素名称 (子元素1|子元素2|子元素3|...|子元素n)>表示这些子元素中只能出现其中一个

更多用来表示元素个数的方式还有

1、+:最少1次

2、?:最多一次

3、*:任意次数

4、无:只能一次

如mybatis-3-config.dtd中定义的

<!ELEMENT databaseIdProvider (property*)> 
表示元素databaseIdProvider可以出现任意个property子元素

<!ELEMENT settings (setting+)>
表示元素settings最少有一个setting子元素

<!ELEMENT environment (transactionManager,dataSource)>
表示元素environment中的子元素必须有且只有一个transactionManager和dataSource子元素

当然上面这些方式都是按照元素是包含其他子元素来定义的,除了这种方式来定义元素外,我们还可以根据元素里包含的子元素类型不同来定义,如:

<!ELEMENT 元素名称 (#PCDATA)>

表示此元素仅仅包含一般文字,是基本元素。在mybatis-3-config.dtd中是没有定义基本元素的。

在mybatis-3-config.dtd中,除了以 <!ELEMENT 元素名称 元素内容> 来定义元素以外,还有发现以下面这种方式来定义元素的

<!ELEMENT property EMPTY>
这是用来定义元素的类型的,元素可以根据是否拥有子元素来区分为ANY和EMPTY两种类型,ANY表示该元素下可以包含任意已经被设定过的元素,出现的次数和顺序也不受限制,并且除了可以包含子元素外还可以包含一般的文字。而EMPTY表示该元素为空元素,是单独存在,没有</元素>这样的结束标记的。例如

<!ELEMENT property EMPTY>
<!ELEMENT setting EMPTY>
<!ELEMENT typeAlias EMPTY>
<!ELEMENT typeHandler EMPTY>
<!ELEMENT mapper EMPTY>
<!ELEMENT package EMPTY>
这些元素都是空元素,只能以<property />这种写法来结束,除了定义元素以外,我们还可以定义常量供DTD和XML文件使用,声明方式如下:

<!ENTITY 元素名称 "元素内容">例如下面我们定义一个author常量

<!ENTITY author "张三">在XML中引用常量author的方式:以&开头,以;结尾,即&author; 如:

<name>&author;</name>

前面为大家介绍了元素的定义方式,下面介绍元素的属性定义,在mybatis-3-config.dtd中,大家可以看到在<!ELEMENT>标签下面通常都会紧跟另一个标签<!ATTLIST>,<!ATTLIST>标签是用来约束元素属性的,例如:

<!ELEMENT typeHandler EMPTY>
<!ATTLIST typeHandler
javaType CDATA #IMPLIED
jdbcType CDATA #IMPLIED
handler CDATA #REQUIRED
>
我们可以按照下面方式来解读

<!ATTLIST 元素名称
属性1名称 属性1值类型 属性1内定值种类
属性2名称 属性2值类型 属性2内定值种类
属性3名称 属性3值类型 属性3内定值种类
>
其中属性值的类型主要包括

1、CDATA:字符串

2、(值1|值2|值3):枚举

3、ID:唯一标识,在同一个XML文件中不可重复

还有一些其他的类型暂时未列出也不做介绍,基本不怎么用到,比如nmtoken、nmtokens、idref、idrefs、entity、entities、notation

属性内定值种类包括

1、#REQUIRED:必须的

2、#IMPLIED:可选的

3、#FIXED:固定值

4、字符串:默认值
我们简单举个例子,定义一个员工元素和属性

<!ELEMENT 员工 EMPTY> <!ATTLIST 员工 姓名 CDATA #REQUIRED 性别 (男|女) "男" 身份证号 ID #IMPLIED 所属星球 CDATA #FIXED "地球" >

在XML中我们可以设置员工元素如下:

<员工 姓名="张三" 身份证号="123456" />它等效于下面方式

<员工 姓名="张三" 性别="男" 身份证号="123456" 所属星球="地球" /></span>

如果你再一定一个员工

<员工 姓名="李四" 身份证号="123456" />解析会报错,因为身份证号值类型的约束为ID,是唯一的,不可重复

OK,DTD部分就介绍到这

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 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轻松学习总节篇