XML语义约束

  • XML文档结构正确,但可能不是有效的
  • 例如:员工档案XML中绝对不允许出现”植物品种”标签。XML语义约束就是用于规定XML文档中允许出现哪些元素
  • XML语义约束有两种定义方式:DTD与XML Schema

Doucument Type Defintion

  • DTD(Document Type Definition ,文档类型定义)是一种简单易用的语义约束方式

  • DTD文件扩展名为.dtd

    1
    2
    3
    4
    5
    6
    hr.dtd
    <!ELEMENT hr(employee+)>
    <!ELEMENT employee (name,age,salaey,department)>
    <!ATTLIST employee no CDATA "">
    <!ELEMENT name (#PCDATA)>

DTD定义节点

  • 利用DTD中的<!ELEMENT>标签,我们可以定义XML文档中允许出现的节点及数量,以hr.xml为例:

    1
    2
    3
    4
    5
    6
    7
    <!--定义hr(主节点)下只允许出现1个employee子节点-->
    hr.dtd
    <!ELEMENT hr(employee+)>
    <!ELEMENT employee (name,age,salaey,department)><!--employee节点下必须包含以下四个节点,且按顺序出现-->
    <!ATTLIST employee no CDATA "">
    <!ELEMENT name (#PCDATA)><!--定义name标签体只能是文本,#PCDATA代表文本元素-->

  • 如某字节点需要多次重复出现,则需要在子节点后增加相应的描述

    1
    2
    3
    4
    5
    <!--hr节点下最少出现1个employee子节点-->
    <!ELEMENT hr(employee+)>
    <!--hr节点下可出现0..n个employee子节点-->
    <!ELEMENT hr(employee*)>
    <!--hr-->

XML引用DTD文件

  • 在XML中使用<!DOCTYPE>标签来引用DTD文件

    1
    2
    3
    4
    书写格式:
    <!DOCTYPE 根节点 SYSTEM "dtd文件路径">
    示例:
    <!DOCTYPE hr SYSTEM "hr.dtd">
  • 创建DTD文件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE hr SYSTEM "hr.dtd"><!--XML文件引用DTD文件-->
    <!--人力资源管理系统-->
    <hr>
    <employee no="3309">
    <name>张三</name>
    <age>31</age>
    <salary>4000</salary>
    <department>
    <dname>会计部</dname>
    <address>XX大厦-B103</address>
    </department>
    </employee>

    <employee no="3310">
    <name>李四</name>
    <age>23</age>
    <salary>4000</salary>
    <department>
    <dname>工程部</dname>
    <address>XX大厦-B104</address>
    </department>
    </employee>
    </hr>
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    <?xml version="1.0" encoding="UTF-8" ?><!--dtd文件本质上也是xml文件-->
    <!ELEMENT hr (employee+)><!--可以拥有多个employee元素-->
    <!ELEMENT employee (name,age,salary,department)><!--employee主元素下拥有这四个子元素-->
    <!ATTLIST employee no CDATA " "><!--定义employee元素中的属性no-->
    <!ELEMENT name (#PCDATA)><!--定义name子元素为纯文本-->
    <!ELEMENT age (#PCDATA)>
    <!ELEMENT salary (#PCDATA)>
    <!ELEMENT department (dname,address)><!--定义department元素下拥有两个子元素-->
    <!ELEMENT dname (#PCDATA)><!--定义dname子元素为纯文本-->
    <!ELEMENT address (#PCDATA)><!--定义address子元素为纯文本-->

XML Schema

XML Schema的概述

  • XML Schema比DTD更为复杂,提供了更多的功能
  • XML Schema提供了数据类型、格式限定、数据范围等特性XMLX
  • XML Schema是W3C标准

XML Schema文件的具体例子

直接上代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?xml version="1.0" encoding="UTF-8" ?>
<!--人力资源管理系统-->
<!--调用hr-scheam.xsd文件-->
<hr xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="hr-schema.xsd">
<employee no="3309">
<name>张三</name>
<age>19</age>
<salary>4000</salary>
<department>
<dname>会计部</dname>
<address>XX大厦-B103</address>
</department>
</employee>

<employee no="3310">
<name>李四</name>
<age>23</age>
<salary>4000</salary>
<department>
<dname>工程部</dname>
<address>XX大厦-B104</address>
</department>
</employee>
</hr>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
<?xml version="1.0" encoding="UTF-8" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="hr">
<!--complexType标签含义是复杂节点,包含子节点时必须使用这个标签-->
<xs:complexType>
<!--sequence标签包含是子节点必须严格书写,-->
<xs:sequence>
<xs:element name="employee" maxOccurs="10"><!--定义employee节点出现的次数-->
<xs:complexType>
<xs:sequence><!--说明前后顺序-->
<xs:element name="name" type="xs:string"> </xs:element><!--代表的是name子元素是字符串类型,且不能拥有子节点-->
<xs:element name="age">
<!--设置age属性的简单类型约束-->
<xs:simpleType>
<xs:restriction base="xs:integer">
<xs:minInclusive value="18"></xs:minInclusive>
<xs:maxInclusive value="60"></xs:maxInclusive>
</xs:restriction>
</xs:simpleType>
</xs:element>
<!--代表的是salary只允许输入整型,不能拥有子节点-->
<xs:element name="salary" type="xs:integer"></xs:element>
<!--代表的是department,拥有子节点-->
<xs:element name="department">
<xs:complexType><!--说明含有子节点-->
<xs:sequence><!--说明前后顺序-->
<!--代表的是:department节点下的两个子节点,且不能含有其他子节点-->
<xs:element name="dname" type="xs:string"></xs:element>
<xs:element name="address" type="xs:string"></xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
<!--定义employee的no属性,必须是string类型,required表示的是employee下必须存在的-->
<xs:attribute name="no" type="xs:string" use="required"> </xs:attribute><!--定义节点中的属性,名字与数据类型-->
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>