JavaWeb--XML的约束

一、什么是XML约束

​ 在XML技术里,可以编写一个文档来约束一个XML文档的书写规范,约束文档定义了在XML中允许出现的元素名称、属性及元素出现的顺序等等。

二、为什么需要约束

​ 由于xml的标签由用户自己定义,因此在开发的时候,每个人都可以根据自己的需求来定义xml标签,这样导致项目中的xml难以维护,因此需要使用一定的规范机制来约束xml文件中的标签书写。

三、XML约束有哪些

XML的约束有两种,分别为:

  1. XML DTD
  2. XML Schema

四、DTD约束的使用方法

(一)DTD快速入门

第一步:先定义自己的一个XML文件

<?xml version="1.0" encoding="UTF-8"?>
<users>
    <user>
        <name>zhangsan</name>
        <age>23</age>
        <addr>shanghai</addr>
    </user>
    <user>
        <name>lisi</name>
        <age>24</age>
        <addr>beijing</addr>
    </user>
</users>

第二步:书写DTD文件来约束xml文件。

​ DTD文件在定义的时候,扩展名就是dtd。

<?xml version="1.0" encoding="UTF-8" ?>
<!ELEMENT users (user+)>
<!ELEMENT user (name,age,addr)>
<!ELEMENT name (#PCDATA) >
<!ELEMENT age (#PCDATA)>
<!ELEMENT addr (#PCDATA)>

第三步:引入DTD

  1. DTD的引入方式由如下三种
DTD主要用来约束xml文件,DTD可以单独写在文件中,也可以直接定义在xml中,可以在xml中引入第三方的公共DTD。

方式一:
外部DTD的引入方式:外部DTD主要指的一个独立的DTD文件。
首先要书写DTD文件,然后在要被约束的xml文件中引入。
<!DOCTYPE 文档根结点 SYSTEM "DTD文件的URL">
文档根结点 指的是当前xml中的根标签。
SYSTEM  引入的系统中存在文件
"DTD文件的URL" DTD存放的位置

方式二:
引入公共的DTD:
<!DOCTYPE 文档根结点 PUBLIC "DTD名称" "DTD文件的URL">
文档根结点 指的是当前xml中的根标签。
PUBLIC  表示当前引入的DTD是公共的DTD
如:<!DOCTYPE web-app PUBLIC 
		"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
		"http://java.sun.com/dtd/web-app_2_3.dtd">

方式三:
在xml中直接书写DTD
<!DOCTYPE  根标签名 [
具体的标签的约束
]>
  1. 此处,在XML文件中使用的引入方式是使用的第三种
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE users[
    <!ELEMENT users (user+) >    
    <!ELEMENT user (name,age,addr) >    
    <!ELEMENT name (#PCDATA) >    
    <!ELEMENT age (#PCDATA) >    
    <!ELEMENT addr (#PCDATA) >    
]>
<users>
    <user>
        <name>zhangsan</name>
        <age>23</age>
        <addr>shanghai</addr>
    </user>
    <user>
        <name>lisi</name>
        <age>24</age>
        <addr>beijing</addr>
    </user>
</users>

(二)DTD约束语法细节

元素定义:

当定义DTD约束xml时候,这时需要在DTD中使用ELEMENT来定义当前xml中可以出现的标签名称。

格式:
<!ELEMENT 标签名 约束>  约束来限定当前标签中可以有的子标签,或者当前标签中可以书写的内容
在定义标签名的时候,约束中可以使用一些符号标签具体出现次数
?    零次或者一次
*    零次或者多次
+    一次或者多次   
如: users (user+)   表示当前的users标签下可以有一个或者多个user标签

,   用来限定当前的子标签出现的顺序user (name,age,addr)  
如:上面的快速入门中,user标签下只能有name age addr 子标签,并且必须按照name  age  addr的顺序书写
|  user (name|age,addr) user下可以name或者age ,但必须有addr,并且addr必须name或age后面

#PCDATA    表明该元素可包含任何字符数据,但不能在其中包含任何子元素。使用该类型时,要用圆括号括起来
EMPTY      表明该元素不能有任何子元素或文本,仅可以使用属性。
ANY        表明该元素中可以包含任何DTD中定义的元素内容 如:<!ELEMENT note ANY>
<!ELEMENT age EMPTY >  当前的age标签是个空标签,它不能有文本内容。

属性定义:

格式:
<!ATTLIST 标签名 
	属性名 属性的类型  属性的约束
>
	
如果一个标签上有多个属性
<!ATTLIST 标签名 
	属性名 属性的类型  属性的约束
	属性名 属性的类型  属性的约束
	属性名 属性的类型  属性的约束
	......
>
属性值类型:
CDATA:表示属性的取值为普通的文本字符串
ENUMERATED (DTD没有此关键字):表示枚举,只能从枚举列表中任选其一,如(鸡肉|牛肉|猪肉|鱼肉)
ID:表示属性的取值不能重复,属性的值只能由字母,下划线开始,不能出现空白字符

属性的约束
#REQUIRED:表示该属性必须出现
#IMPLIED:表示该属性可有可无
#FIXED:表示属性的取值为一个固定值。语法:#FIXED "固定值"
直接值:表示属性的取值为该默认值
a.使用FIXED约束
<!ATTLIST user
	name CDATA  #FIXED "zhangsan"
>	
<user name=”zhangsan”>

b.使用直接值约束
<!ATTLIST user
	name CDATA "张三"
>
<user />

实体定义:

实体用于为一段内容创建一个别名,以后在XML文档中就可以使用别名引用这段内容了。
在DTD定义中,一条<!ENTITY …>语句用于定义一个实体。
实体可以理解成Java中预先定义好的一个常量,然后xml文件中就可以引入当前这个定义的实体。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE users[
    <!ELEMENT users (user+) >    
    <!ELEMENT user (name,age,addr) >    
    <!ELEMENT name (#PCDATA) >    
    <!ELEMENT age EMPTY >    
    <!ELEMENT addr (#PCDATA) >    
    <!ATTLIST user id ID #REQUIRED >
    <!ENTITY  temp "湖南长沙">
]>

<users>
    <user id="u001">
        <name>zhangsan</name>
        <age></age>
        <addr>&temp;</addr>
    </user>
    <user id="u002">
        <name>lisi</name>
        <age/>
        <addr>&temp;</addr>
    </user>
</users>

五、Schema约束的使用方法

(一) Schema简介

Schema它也来约束xml文件的,DTD在约束xml的时候一个xml中只能引入一个DTD,同时DTD它无法对属性以及标签中的数据做数据类型的限定。
Schema是想要用来代替DTD来约束xml的,但是目前还没实现。
Schema文件本身就是使用xml文件书写的,同时它对需要约束的xml中的数据有严格的限定。学习Schema主要来学习W3C组织定义的如何在Schema中约束xml的标签以及属性,还有属性的数据类型,以及标签中子标签的顺序。
要定义一个Schema文件,这时它的扩展名必须是.xsd。在这个文件中根元素必须是schema。
使用Schema来约束xml,Schema在书写的时候,只需要使用W3C组织提前定义的限定标签即可。

(二)Schema快速入门

第一步:书写xml文件

<?xml version="1.0" encoding="UTF-8"?>
<person xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.itcast.cn/20151111"
xsi:schemaLocation="http://www.itcast.cn/20151111 test.xsd">
	<name>zhangsan</name>
	<name>zhangsan</name>
	<name>zhangsan</name>
	<age>20</age> 
</person>

第二步:定义schema文件

test.xsd

<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.itcast.cn/20151111"
elementFormDefault="qualified">
	<element name="person">
		<complexType>
			<sequence>
                 <!-- <all> -->
                 <!-- <choice> -->
                     <element name="name" type="string" maxOccurs="unbounded"></element>
                      <element name="age" type="int"></element>
                 <!-- </choice> -->
                 <!-- </all>	 -->
			</sequence>
			<attribute name="id1" type="int" use="required"></attribute>
		</complexType>
	</element>
</schema>

(三)对上述文件中相关元素及属性的解释

在schema文件里面
xmlns="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.itcast.cn/20151111"
elementFormDefault="qualified">

xmlns="http://www.w3.org/2001/XMLSchema"
	- 表示当前xml文件是一个约束文件
targetNamespace="http://www.itcast.cn/20151111"
	- 给当前的Schema文件起名字(命名空间),可以自己随便取
	- 作用是当哪个xml要引入这个schema约束的时候,必须通过当前targetNamespace 后面书写的uri地址来引入
elementFormDefault="qualified"
	- 用的很少
在被约束文件里面引入约束文件
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.itcast.cn/20151111"
xsi:schemaLocation="http://www.itcast.cn/20151111 test.xsd">

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	- 表示xml是一个被约束文件
xmlns="http://www.itcast.cn/20151111"
	- 是约束文档里面的 targetNamespace
xsi:schemaLocation="http://www.itcast.cn/20151111 test.xsd">
	- 此属性有两个值。第一个值是需要使用的命名空间。第二个值是供命名空间使用的约束文档的实际位置,两者之间用空格分隔

(四)Schema的名称空间

在XML Schema中,每个约束模式文档都可以被赋以一个唯一的名称空间,名称空间用一个唯一的URI(Uniform Resource Identifier,统一资源标识符)表示。 在Xml文件中书写标签时,可以通过名称空间声明(xmlns),来声明当前编写的标签来自哪个Schema约束文档。

注意:
名称空间的名字语法容易让人混淆,尽管以 http:// 开始,那个 URL 并不指向一个包含模式定义的文件。事实上,这个 URL根本没有指向任何文件,只是一个分配的名字。

(五) Schema约束语法细节

  1. XMLSchema 简易元素和复杂元素
简易元素:指那些仅包含文本的元素。它不会包含任何其他的元素或属性。 
<element name="xxx" type=“string"/>
复杂元素:复杂类型元素是包含子元素或者属性的元素
使用<complexType>:表示复杂类型 ; 
   <sequence>:表示有顺序
   
如:
<element name="person">
    <complexType>
        <sequence>
            <element name="to" type="string" />
            <element name="from" type="string" />
        </sequence>
    </complexType>
</element>
  1. XMLSchema 复杂元素指示器
All:      表示只能出现一次 
Choice:   只能出现其中的一个
Sequence: 元素按照顺序出现 
maxOccurs=“unbounded” 表示出现次数没限制  
如:
<element name="name" type="double" maxOccurs="unbounded"/>

定义属性(必须是复杂元素):<attribute name="p1" type="string" use="required"></attribute>
<any></any>: 表示任意元素,但是必须是约束文档中定义好的

(六)XMLSchema 进阶例子

  1. company.xsd
<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema" 
targetNamespace="http://www.example.org/company" 
elementFormDefault="qualified">
	<element name="company">
		<complexType>
			<sequence>
				<element name="employee">
					<complexType>
						<sequence>
							<!-- 引用任何一个元素 -->
							<any></any>
							<!-- 员工名称 -->
							<element name="name"></element>
						</sequence>
						<!-- 为employee元素添加属性 -->
						<attribute name="age" type="int"></attribute>
					</complexType>
				</element>
			</sequence>
		</complexType>
	</element>
</schema>
  1. department.xsd
<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema"
 targetNamespace="http://www.example.org/department" 
 elementFormDefault="qualified">
 <!-- 部门名称 -->
 <element name="name" type="int"></element>
</schema>
  1. company.xml
<?xml version="1.0" encoding="UTF-8"?>
<!-- 数据文件 引用多个Schema -->
<company xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
     xmlns:comp = "http://www.example.org/company"
	xmlns:dept="http://www.example.org/department"
	
	xsi:schemaLocation="http://www.example.org/company company.xsd     				http://www.example.org/department department.xsd" 
>
	<employee age="30">
		<!-- 部门名称 --> 
		<dept:name>100</dept:name>
		<!-- 员工名称 -->
		<comp:name>王晓晓</comp:name>   
	</employee>
</company>

注意:

由于一个标签上不能出现两个同名的属性,所以在引入多个约束文档时,需要给名称空间起一个别名。如company.xml中的第3,4,5行。在之后指定哪一个约束文档时,只需要使用别名即可。

Java新手,若有错误,欢迎指正!

posted @ 2020-04-10 18:11  跑调大叔!  阅读(326)  评论(0编辑  收藏  举报