XML文档约束之DTD

       在任何一个XML文档中应包括头部(header)和内容(content)这两部分。其中,头部除了要声明所遵循的标准和字符集编码之外,还可以通过引入相关的约束来保证整个文档结构的完整性。目前,比较常用的约束手段有如下三种方式:

       1)DTD:XML1.0规范的一部分,简单但不灵活;

       2)Schema:灵活但复杂;

       3)RELAX NG:针对XML Schema复杂性而产生的一种约束模式,融合了DTD的简单性和XML Schema的灵活性,但不具备XML Schema的全部特性。      

        DTD的约束主要涉及到元素和当前元素属性的定义,包括:元素的名称、元素所包含的内容、子元素的个数和顺序、元素所具有的属性、属性的数据类型和取值范围等,根据具体的应用,这里所述的内容不是都需在DTD中有所体现。

 

1.定义元素

       包括根元素在内的所有元素都需要利用关键字ELEMENT来定义,其语法如下:

        <!ELEMENT 元素名 内容模式 >

        其中红色部分的内容为固定不变的,而内容模式是定义当前元素应包含的子元素(组),子元素出现的个数和顺序,以及是否可包含文本内容等。

 

2.元素的内容模式

      即上述内容模式可能是由如下几种情况之一构成的:

       1)  (子元素1 | 子元素2 | 子元素n)   或 (子元素1,子元素2,子元素n)

       其中,“|”号表示元素之间“”的关系,即表示可以包含子元素1,或子元素2,或子元素3。另外,还可以用逗号“,”来分割,表示这些子元素出现在父元素中的先后次序。

       在这种情况下,还可以用“量词”来量化各子元素(组)出现的次数。

       ? :0次或1次(0|1)

       + :一次或多次(1...N)

       *  :0次或多次(0...N)

       无量词作用时,则默认表示有且必须出现一次

       例如:

       <!ELEMENT a(sa?) >表示子元素sa在元素a中那么不出现,要么只出现一次,而<!ELEMENT a(sa,sb,sc)+ >则表示sa、sb和sc至少依次嵌套在a元素中一次。

       2) (#PCDATA)

       表示当前元素只能包含纯文本内容。

       例如,针对元素a,

              <a>test</a>、<a></a>和</a>都是合法的,

              而<a><sa>test<sa></a>是非法的。

       3) EMPTY

       表示当前元素不能包含任何嵌套的子元素和文本内容。例如,针对元素a,只有在<a />和<a></a>这两种情况下是合法的。

       4) ANY

       表示当前元素可以包含任意数量和顺序的子元素和文本内容。在这种情况下,和没有引入DTD时是一样的效果,只要遵循XML文档结构的基本规则即可。

       在定义元素时,内容模式部分是不能被省略的。例如,当我们定义一个bean元素时,即使对它内部嵌套没有明确的内容约束时,也需要在最后加上ANY来加以说明:<!ELEMENT bean ANY >

       上述的内容模式还可以组合使用,例如<!ELEMENT bean (a|(b*,c)+)? >。

 

3.定义元素的属性

        定义元素的属性是通过关键字ATTLIST来进行的,其语法如下:

        <!ATTLIST 元素名 属性名 属性值类型/取值范围 是否可选>

        其中红色部分的内容为固定不变的,元素名是指拥有这些属性的元素,而“属性名 属性值类型/取值范围 是否可选”是定义某一个属性所必须具备的三要素,称为属性列表。另外,当前元素的所有属性都应该在同一个<!ATTLIST >中定义,这意味着当有n个属性时,则应该在同一个<!ATTLIST >中定义n个属性列表。

        

4.属性列表

        1)属性名

         即一般的文本值,只要符合XML基本的规范即可。

         2)属性值类型/取值范围         当某个属性无明确的取值范围时,则需指定该属性值的类型,一般就是一个文本类型CDATA;当某个属性有明确的取值范围时,则必须用括号“()”将所有备选值括起来,并且备选值之间用“|”分割,表示这是一个n选一的操作。例如:

         type (string | int | boolean)

         表示type属性值只能是string、int或boolean。

         3)是否可选

         可用#REQUIRED(必选)#IMPLIED(可选)来表示,根据实际的应用场景来设置即可。例如:                  type CDATA #REQUIRED

         表示必选的type属性的值为任意的文本字符。

 

5.定义DTD

    temple.dtd

 

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

<!-- 定义XML根元素temple,其内有0个或多个bean元素  -->
<!ELEMENT templet (bean*)>

<!-- 
	1.定义bean元素,其内有0个或多个property元素  
	2.定义bean元素属性:
	  1)name  任意文本值  可选
	  2)class 任意文本值   必选
-->
<!ELEMENT bean (property*)>
<!ATTLIST bean 
    name    CDATA #IMPLIED
	class   CDATA #REQUIRED
>

<!-- 
	1.定义property元素,无任何嵌套的子元素和文本内容
	2.定义property元素属性:
	  1)name  任意文本值  必选
	  2)type  括号内所指定的某一个值  可选
	  3)ref   任意文本值  可选
-->
<!ELEMENT property EMPTY >
<!ATTLIST property 
    name    CDATA #REQUIRED
	type    (
			 java:boolean   |
			 java:byte      |
			 java:char      |
			 java:double    |
			 java:float     |
	         java:long      |
			 java:integer   |
			 java:short     |
			 java:string    
			) #IMPLIED
	ref     CDATA #IMPLIED 
>

 

6.引入DTD

       在某个XML件头中,可通过<!DOCTYPE来引入相应的DTD文件,它有两种引入方式:

       1)远程引入

        DTD文件可能是在一个公用的网络目录上,供若干个互联网用户共同使用。其语法如下:

        <!DOCTYPE DTD标识符 PUBLIC "DTD公共标识" "DTD系统标识" >

        其中红色部分为远程引入时的固定写法。

         DTD标识符:可以为任意字符串,不过一般就取名为DTD中定义的根元素名称;

         PUBLIC:远程引入的关键字        

         DTD公共标识以“-//”开头。

         DTD系统标识:一般就是用来指定DTD文件的URI。当公共标识无法解析时,则就用系统标识来进行。

         例如,Struts2的DTD引入如下:

         <!DOCTYPE struts PUBLIC
               "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
               "http://struts.apache.org/dtds/struts-2.0.dtd">

        2)本地引入

        即引入用户系统中定义的DTD文件,其语法如下:

        <!DOCTYPE DTD标识符 SYSTEM "DTD文件路径" >

        其中红色部分为远程引入时的固定写法。

        DTD标识符:(与远程引入的规则一样)

        SYSTEM:本地引入的关键字

        DTD文件路径:DTD相对于当前XML文件的路径

        例如,将第5部分定义的temple.dtd放到与temple.xml的同一个目录下后,在XML引入如下内容:

        

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

<!-- 引入本地的DTD文件 -->
<!DOCTYPE temple SYSTEM "temple.dtd">

<temple>
	
	<bean name="user" class="com.daniele.appdemo.test.domain.User">
		<property name="id" type="java:long" />
		<property name="name" type="java:string" />
		<property name="age" type="java:integer"/>
		<property name="mail" type="java:string" />
	</bean>
	
</temple>
       在Eclipse中,当我们在文档的相应位置键入"Alt"+"/"组合键后,将会看到一系列的备选值,而这些备选值就是在 temple.dtd定义的。

 

你可能感兴趣的:(xml,dtd)