目前主流的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
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; 如:
前面为大家介绍了元素的定义方式,下面介绍元素的属性定义,在mybatis-3-config.dtd中,大家可以看到在<!ELEMENT>标签下面通常都会紧跟另一个标签<!ATTLIST>,<!ATTLIST>标签是用来约束元素属性的,例如:
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部分就介绍到这 <name>&author;</name>
<!ELEMENT typeHandler EMPTY>
<!ATTLIST typeHandler
javaType CDATA #IMPLIED
jdbcType CDATA #IMPLIED
handler CDATA #required
>
我们可以按照下面方式来解读
<!ATTLIST 元素名称
属性1名称 属性1值类型 属性1内定值种类
属性2名称 属性2值类型 属性2内定值种类
属性3名称 属性3值类型 属性3内定值种类
>
其中属性值的类型主要包括
我们简单举个例子,定义一个员工元素和属性