【XML】XML约束(DTD/Schema)

1.什么是XML约束?

一个XML文档一旦有了约束,那么这个XML文档就只能使用约束中创建的元素及属性。

如果约束没有创建<a>元素,那么XML文档就不能使用<a>元素

因为xml文档是可以自定义元素的,这会让使用xml文档的应用程序无法知道xml文档的真实结构。

2.DTD:

dtd是平面式文档,dtd文件不是xml文档,通常扩展名为“.dtd”。它是最早的xml约束

 

>>>DTD元素定义

1 定义元素的语法

使用ELEMENT声明元素:<!ELEMENT 元素名 内容类型内容>

例如:<!ELEMENT name (#PCDATA)>

表示name元素的内容为文本数据

 

2 元素类型

元素类型可以是ANYEMPTY

<!ELEMENT stu ANY>:表示stu元素的内容可以是任意元素,也可以是文本数据,也可以是文本数据+子元素,反正就是任意。

<!ELEMENT stu EMPTY>:表示stu不能有任何内容,即空元素。例如:<stu/>。

 

3 元素内容

元素内容可以是文本数据,也可以是子元素

<!ELEMENT stu (#PCDATA)>表示stu元素内容为文本,例如:<stu>hello</stu>

<!ELEMENT stu (name)>表示stu元素内容为name子元素,例如<stu><name></name><stu>,但要注意,如果<name>元素没有声明,那么就会出错。

 

4 子元素出现次数

可以使用“?”、“*”、“+”来指定子元素的出现次数

<!ELEMENT stu (name?)>表示stu元素可以有0~1个name子元素,即name子元素可有可无。

<!ELEMENT stu(name*)>表示stu元素可以有0~n个name子元素;

<!ELEMENT stu(name+)>表示stu元素可以有1~n个name子元素。

 

5 多个子元素

<!ELEMENT stu (name,age,sex)>表示stu必须有三个子元素,分别是name、age、sex,并且子元素出现的顺序也要与声明的顺序一致

 

6 枚举子元素

<!ELEMENT stu (name | age | sex)表示stu只有一个子元素,可以是name、age、sex中的任意一个。

 

7 复合声明1

<!ELEMENT stu (name | age | sex)?>表示stu元素可以有0~1个(name | age | sex),而(name | age | sex)表示name、age、sex其中的一个。

<stu></stu>

<stu><name/></stu>

<stu><age/></stu>

<stu><sex/></stu>

 

8 复合声明2

  <!ELEMENT stu (name | age | sex)*>表示stu元素可以有0~n个(name | age | sex),而(name | age | sex)表示name、age、sex其中的一个。

<stu></stu>

<stu><name/><name/></stu>

<stu><name/><age/><age/></stu>

<stu><name/><age/><name/><sex/><sex/></stu>

 

9 复合声明3

<!ELEMENT stu (name | age | sex)+>表示stu元素可以有1~n个(name | age | sex),而(name | age | sex)表示name、age、sex其中的一个。

<stu><age/></stu>

<stu><name/><name/></stu>

<stu><name/><age/><age/></stu>

<stu><name/><age/><name/><sex/><sex/></stu>

>>>DTD属性定义

1 属性定义的格式

ATTLIST = Attribute List

<!ATTLIST 元素名

                    属性名1 属性类型 设置说明

                    属性名2 属性类型 设置说明

...>

<!ATTLIST student number CDATA #REQUIRED>表示student元素的number为文本类型,这个属性是必须的。

最常见的属性类型:CDATA,表示文本类型;

最常见的设置说明1:#REQUIRED,表示属性是必须的。

最常见的设置说明2:#IMPLIED,表示属性是可选的。

 

2 属性类型

2.1

>> CDATA

Character Data字符数据:属性值为任意文本数据(字符类型);

2.2

>> Enumerated:

属性值必须是枚举列表中的一个

Enumerated不是关键字,定义枚举类型的属性需要给出枚举列表。当属性值为枚举类型时,那么这个属性的取值必须是枚举列表中的一个值。

<!ATTLIST student sex (male | female) #IMPLIED> 表示student的sex属性取值必须是male或者是female。并且这个属性是可选的。

2.3

>> ID:

一个元素最多只能有一个ID 属性,ID属性用来表示元素唯一性的唯一标识。ID属性就相当与元素的身份证号,必须是唯一标识!

如果把student元素的number属性设定为ID类型,那么每个student元素的number属性值必须是唯一的,并且ID类型的属性值不能以数字开头。

<!ATTLIST student number ID #REQUIRED> 表示student的number属性值是ID类型,这说明student元素的number属性值必须是唯一的,不能和其他student的number属性值相同。

<student number=”czbk_1001”/>

<student number=”czbk_1002”/>

 

注意:不能以数字开头

不同标签的ID属性值也不能相同。

如果<a>元素有一个ID属性a

如果<b>元素有一个ID属性b

<a a=”abc”/>

<b b=”abc”/>

上面也是错误的,因为ID属性的值是不可以相同的。

 

>>>导入DTD方式

导入本地DTD文件:

<?xml version="1.0" encoding="utf-8" standalone="no" ?>

<!DOCTYPE students SYSTEM "students.dtd">

在XML中指定内部DTD:

<?xml version="1.0" encoding="utf-8" standalone="no" ?>

<!DOCTYPE students [

<!ELEMENT students (student+)>

<!ELEMENT student (name, age, sex)>

<!ELEMENT name (#PCDATA)>

<!ELEMENT age (#PCDATA)>

<!ELEMENT sex (#PCDATA)>

]>

在XML中指定外部公共DTD:

<?xml version="1.0" encoding="utf-8" standalone="no" ?>

<!DOCTYPE students PUBLIC "//////DTD名称///////" "//////DTD网址///////">

 

>>>实例

<!ELEMENT students (student+)>

<!ELEMENT student (name,age,sex)>

<!ELEMENT name (#PCDATA)>

<!ELEMENT age (#PCDATA)>

<!ELEMENT sex (#PCDATA)>

解读上面DTD:

  1. students元素中可以包含1~n个student元素;
  2. student元素中必须包含name、age、sex元素,而且顺序也是固定的;
  3. name元素内容为文本,即字符串;
  4. age元素内容为文本;
  5. sex元素内容为文本。

3.Schema: 

schema本身也是xml文档,它比dtd要更加强大,通常扩展名为“.xsd”。它是新的xml文档约束,用来替代dtd

<?xml version="1.0"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
	<xsd:element name="students" type="studentsType"/>
	<xsd:complexType name="studentsType">
		<xsd:sequence>
			<xsd:element name="student" type="studentType" minOccurs="0" maxOccurs="unbounded"/>
		</xsd:sequence>
	</xsd:complexType>
	<xsd:complexType name="studentType">
		<xsd:sequence>
			<xsd:element name="name" type="xsd:string"/>
			<xsd:element name="age">
				<xsd:simpleType>
					<xsd:restriction base="xsd:integer">
						<xsd:maxInclusive value="100"/>
						<xsd:minInclusive value="0"/>
					</xsd:restriction>
				</xsd:simpleType>
			</xsd:element>
			<xsd:element name="sex">
				<xsd:simpleType>
					<xsd:restriction base="xsd:string">
						<xsd:enumeration value="男"/>
						<xsd:enumeration value="女"/>
					</xsd:restriction>
				</xsd:simpleType>
			</xsd:element>
		</xsd:sequence>
		<xsd:attribute name="number" type="xsd:string"/>
	</xsd:complexType>
</xsd:schema>

对应的XML文档

<?xml version="1.0" encoding="utf-8" standalone="no" ?>
<students xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:noNamespaceSchemaLocation="students.xsd">
    <student number="ID_1001">
        <name>张三</name>
        <age>23</age>
        <sex>男</sex>
    </student>
    <student number="ID_1002">
        <name>李四</name>
        <age>32</age>
        <sex>女</sex>
    </student>
    <student number="ID_1003">
        <name>王五</name>
        <age>50</age>
        <sex>男</sex>
    </student>
</students> 

xmlns是名称空间,是用来处理XML元素或属性的名字冲突问题。可以理解为Java中的包

包的作用就是用来处理类的名字冲突问题

猜你喜欢

转载自blog.csdn.net/TypantK/article/details/82750944