XML约束

本文详细介绍了XML约束的概念,包括常用的DTD和Schema约束。DTD(文档类型定义)是XML文档的一种约束,用于规定XML文件的结构。而XML Schema是更强大的约束工具,支持更多数据类型和名称空间,是DTD的现代替代品。文中通过实例演示了DTD和Schema的使用,包括元素定义、属性定义、引入方式以及名称空间的声明。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

XML约束

1、概念

一个用来约束XML文档的书写规范的文件

2、常用的约束

  • XML DTD
  • XML Schema

3、DTD约束

① 概念

DTD(Document Type Definition),文档类型定义

文件扩展名是(*.dtd)

② 语法

(1)元素定义

使用 ELEMENT 来声明一个XML元素

<!ELEMENT 父标签 (子标签 | 子标签 | 子标签)>
用 | 分割表示子标签只能是其中一个

<!ELEMENT 父标签 (子标签, 子标签, 子标签)>
用 逗号 分割表示子标签的顺序必须和声明时的一致

<!ELEMENT 父标签 (子标签 | 子标签 | 子标签)*>
子标签的顺序可以是无序的

使用通配符来控制子标签出现的次数

<!ELEMENT 父标签 (子标签?)>
子标签出现零次或一次

<!ELEMENT 父标签 (子标签*)>
子标签出现零次或多次

<!ELEMENT 父标签 (子标签+)>
子标签出现一次或多次

如果标签没有子标签(自结束标签),则可以声明为 EMPTY

<!ELEMENT 标签名 EMPTY>

如果不限制标签的内容,则可以使用 ANY

<!ELEMENT 标签名 ANY>

如果子标签的内容需要解析器来解析,则可以使用 #PCDATA【被解析的字符数据(Parsed Character Data)】

<!ELEMENT 标签名 (#PCDATA)>

(2)属性定义

使用 ATTLIST 来声明元素的属性

<!ATTLIST 元素名
属性名称 属性类型 属性类型 默认值
属性名称 属性类型 属性类型 默认值
>

属性类型:
CDATA           值为字符数据 (character data)【不会被解析器解析的文本】
(en1|en2|..)    此值是枚举列表中的一个值

属性值说明有3类:
#REQUIRED         属性值是必需的
#IMPLIED          属性不是必需的
#FIXED "value"    属性值是固定的

默认值:
注意:需要用引号引起来;如果属性类型是#REQUIRED或#IMPLIED,则不允许有默认值

③ 引入方式

  1. 内部引入:

    直接在XML文件内编写约束(一般不用)

    示例

    <?xml version="1.0" encoding="UTF-8"?>
    
    <!DOCTYPE animal [
    <!ELEMENT animal (#PCDATA)>
    
    <!ATTLIST animal
    name CDATA #REQUIRED
    >
    ]>
    
    <animal name="Tom">Cat</animal>
    
  2. 外部引入:

    DTD约束是一个独立的文件,并在XML中引入

    <!DOCTYPE 文档根节点 SYSTEM "DTD文件路径">
    

    DTD文件在本地

    <!DOCTYPE 文档根节点 PUBLIC "DTD名称" "DTD文件的URL路径">
    
    例如:
    <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
    

    DTD文件在网络上

④ 示例一

XML DTD文件

<?xml version="1.0" encoding="UTF-8"?>
<!ELEMENT person (name?, age?, gender?, live?)>

<!ELEMENT name (#PCDATA)>

<!ELEMENT age EMPTY>
<!ATTLIST age
value CDATA #REQUIRED
>

<!ELEMENT gender EMPTY>
<!ATTLIST gender
value (man | woman) #REQUIRED
>

<!ELEMENT live EMPTY>
<!ATTLIST live
value CDATA #FIXED "yes"
>

XML文件

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE person SYSTEM "person.dtd">
<person>
    <name>Tom</name>
    <age value="14" />
    <gender value="man" />
    <live value="yes" />
</person>

⑤ 示例二

XML-DTD文件

<?xml version="1.0" encoding="UTF-8"?>
<!ELEMENT users (user+)>

<!ELEMENT user (name?, age?, gender?, (height | weight)*)>

<!ELEMENT name (#PCDATA)>

<!ELEMENT age EMPTY>
<!ATTLIST age
value CDATA #REQUIRED
>

<!ELEMENT gender EMPTY>
<!ATTLIST gender
value (man | woman) #REQUIRED
>

<!ELEMENT height EMPTY>
<!ATTLIST height
value CDATA #IMPLIED
>

<!ELEMENT weight EMPTY>
<!ATTLIST weight
value CDATA "0"
>

XML文件

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE users SYSTEM "user.dtd">
<users>
    <user>
        <name>张三</name>
        <age value="14" />
        <gender value="man" />
        <height value="174" />
        <weight value="65" />
    </user>
    <user>
        <name>李四</name>
        <age value="12" />
        <gender value="woman" />
        <weight value="50" />
        <height value="165" />
    </user>
    <user>
        <name>王五</name>
        <age value="17" />
        <gender value="man" />
    </user>
</users>

4、Schema约束

① 概念

XML Schema也是一种用于定义和描述XML文档结构与内容的模式语言

它是为了弥补XML DTD的局限性

文件扩展名是(*.xsd)

② 对比DTD

  • XML Schema符合XML的语法结构
  • DOM、SAX等XML API能很容易地解析出XML Schema文档中的内容
  • XML Schema对namespace(名称空间)有着很好地支持
  • XML Schema支持更多的数据类型,也支持自定义数据类型
  • XML Schema有着更强的语法约束力
  • XML Schema比XML DTD更为复杂,它是W3C组织的标准,是基于XML DTD的替代者

③ 语法

(1)定义标签

schema的所有约束内容,需要写在 schema标签里

固定语法格式:

<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns="名称空间"
            xmlns:xsd="http://www.w3.org/2001/XMLSchema"
            targetNamespace="名称空间"
            elementFormDefault="qualified">
    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
</xsd:schema>

elementFormDefault属性用来声明自定义标签的约束,其表示将所有声明的元素和属性都关联到指定的名称空间里,qualified表示全部元素和属性,unqualified表示只关联根元素

(2)名称空间

所有的schema文件都要有一个namespace,它用一个唯一的URI(Uniform Resource Identifier,统一资源标识符)来表示,该URI不一定存在

声明:URI写在 schema 标签里的 xmlnstargetNamespace 属性里

<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns="http://???"
            xmlns:xsd="http://www.w3.org/2001/XMLSchema"
            targetNamespace="http://???"
            elementFormDefault="qualified">
    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />

    <xsd:element name="根标签名">
    </xsd:element>
</xsd:schema>

引用:需要将namespace和xsd文件路径(中间用空格隔开)都写在 XML根元素的 xsi:schemaLocation 属性里

<?xml version="1.0" encoding="UTF-8"?>
<根标签名 xmlns="http://???"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://??? ???.xsd">
</根标签名>

如果是引用多个schema的namespace,就需要取别名。而取别名的方式就是 xmlns:别名

也就是说如果引入了n个schema,则需要取n-1个别名

注意在schema声明里,需要指定 any 标签,否则就无法声明被引入的schema

声明:

<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns="http://???"
            xmlns:xsd="http://www.w3.org/2001/XMLSchema"
            targetNamespace="http://???">
    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />

    <xsd:element name="根标签名">
        <xsd:complexType>
            <xsd:sequence maxOccurs="unbounded">
                <!-- 注意这个 -->
                <xsd:any />
            </xsd:sequence>
        </xsd:complexType>
    </xsd:element>
</xsd:schema>
根标签


<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns="http://???"
            xmlns:xsd="http://www.w3.org/2001/XMLSchema"
            xmlns:别名="被引入名称空间"
            targetNamespace="http://???"
            elementFormDefault="qualified">
    <xsd:import namespace="被引入名称空间" schemaLocation="被引入xsd文件" />

    <xsd:element name="标签名" />
</xsd:schema>
被引入标签

引用:

<?xml version="1.0" encoding="UTF-8"?>
<根标签名 xmlns="http://???"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns:别名="http://???"
         xsi:schemaLocation="http://??? ???.xsd
         http://??? ???.xsd">
    <别名:标签名 />
</根标签名>

(3)声明标签

使用 element 标签来指定元素标签,其 name 属性是标签的名称

<xsd:element name="标签名">
</xsd:element>

通过 type 属性,来指定其标签填充的数据类型

<xsd:element name="标签名" type="xsd:string" />
字符串

<xsd:element name="标签名" type="xsd:integer" />
整数

<xsd:element name="标签名" type="xsd:boolean" />
逻辑

<xsd:element name="标签名" type="xsd:date" />
日期(yyyy-MM-dd)

<xsd:element name="标签名" type="xsd:time" />
时间(HH:mm:ss)

<xsd:element name="标签名" type="xsd:dateTime" />
日期时间(yyyy-MM-ddTHH:mm:ss)
注意日期和时间之间的“T”

通过 any 标签,来指定子标签可以是任意内容(标签/数据类型)

<xsd:element name="根标签名">
    <xsd:complexType>
        <xsd:sequence>
            <xsd:any />
        </xsd:sequence>
    </xsd:complexType>
</xsd:element>

在元素标签里使用 complexType 标签来指定其内容是 复合 类型

<xsd:element name="标签名">
    <xsd:complexType>
    </xsd:complexType>
</xsd:element>

在复合标签里使用 sequence 标签来指定其子元素标签的出现次数(最多或最少)

<xsd:element name="标签名">
    <xsd:complexType>
        <xsd:sequence maxOccurs="unbounded">
        </xsd:sequence>
    </xsd:complexType>
</xsd:element>
不限制最多次数

<xsd:sequence maxOccurs="1">
</xsd:sequence>
最多出现一次

<xsd:sequence minOccurs="1">
</xsd:sequence>
最少出现一次

④ 示例一

XML schema文件

<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns="http://???/schema/person"
            xmlns:xsd="http://www.w3.org/2001/XMLSchema"
            targetNamespace="http://???/schema/person"
            elementFormDefault="qualified">
    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />

    <xsd:element name="person">
        <xsd:complexType>
            <xsd:sequence maxOccurs="unbounded">
                <xsd:element name="name" type="xsd:string" />
                <xsd:element name="age" type="xsd:integer" />
                <xsd:element name="live" type="xsd:boolean" />
                <xsd:element name="date" type="xsd:date" />
                <xsd:element name="time" type="xsd:time" />
                <xsd:element name="birthday" type="xsd:dateTime" />
            </xsd:sequence>
        </xsd:complexType>
    </xsd:element>
</xsd:schema>

XML文件

<?xml version="1.0" encoding="UTF-8"?>
<person xmlns="http://???/schema/person"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://???/schema/person person.xsd">
    <name>张三</name>
    <age>14</age>
    <live>true</live>
    <date>2020-12-16</date>
    <time>02:31:00</time>
    <birthday>2020-12-16T02:31:00</birthday>
</person>

⑤ 示例二

XML schema文件

person.xsd

<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns="http://???/schema/person"
            xmlns:xsd="http://www.w3.org/2001/XMLSchema"
            targetNamespace="http://???/schema/person">
    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />

    <xsd:element name="person">
        <xsd:complexType>
            <xsd:sequence>
                <xsd:choice minOccurs="0" maxOccurs="unbounded">
                    <xsd:element ref="body" />
                    <xsd:any namespace="##other" processContents="strict" minOccurs="0" maxOccurs="unbounded" />
                </xsd:choice>
            </xsd:sequence>
            <xsd:attribute name="name" type="xsd:string" />
        </xsd:complexType>
    </xsd:element>

    <xsd:element name="body">
        <xsd:complexType>
            <xsd:complexContent>
                <xsd:extension base="xsd:string">
                    <xsd:group ref="bodyElements" />
                    <xsd:attributeGroup ref="bodyAttributes" />
                </xsd:extension>
            </xsd:complexContent>
        </xsd:complexType>
    </xsd:element>

    <xsd:group name="bodyElements">
        <xsd:sequence>
            <xsd:choice minOccurs="0" maxOccurs="unbounded">
                <xsd:element ref="constructor-arg" />
                <xsd:any namespace="##other" processContents="strict" minOccurs="0" maxOccurs="unbounded" />
            </xsd:choice>
        </xsd:sequence>
    </xsd:group>

    <xsd:element name="constructor-arg">
        <xsd:complexType>
            <xsd:complexContent>
                <xsd:extension base="xsd:string">
                    <xsd:attribute name="index" type="xsd:integer" />
                </xsd:extension>
            </xsd:complexContent>
        </xsd:complexType>
    </xsd:element>

    <xsd:attributeGroup name="bodyAttributes">
        <xsd:attribute name="name" type="xsd:string" />
        <xsd:attribute name="age" type="xsd:integer" />
    </xsd:attributeGroup>
</xsd:schema>

pack.xsd

<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns="http://???/schema/pack"
            xmlns:xsd="http://www.w3.org/2001/XMLSchema"
            xmlns:person="http://???/schema/person"
            targetNamespace="http://???/schema/pack"
            elementFormDefault="qualified">
    <xsd:import namespace="http://???/schema/person" schemaLocation="person.xsd" />

    <xsd:element name="bag">
        <xsd:complexType>
            <xsd:sequence maxOccurs="unbounded">
                <xsd:element name="front">
                    <xsd:complexType>
                        <xsd:sequence maxOccurs="1">
                            <xsd:element name="name" type="xsd:string" />
                        </xsd:sequence>
                    </xsd:complexType>
                </xsd:element>
                <xsd:element name="back">
                    <xsd:complexType>
                        <xsd:sequence maxOccurs="unbounded">
                            <xsd:element name="one" type="xsd:string" />
                            <xsd:element name="two" type="xsd:string" />
                            <xsd:element name="three" type="xsd:string" />
                        </xsd:sequence>
                    </xsd:complexType>
                </xsd:element>
            </xsd:sequence>
        </xsd:complexType>
    </xsd:element>
</xsd:schema>

XML文件

<?xml version="1.0" encoding="UTF-8"?>
<person xmlns="http://???/schema/person"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:pack="http://???/schema/pack"
        xsi:schemaLocation="http://???/schema/person person.xsd
        http://???/schema/pack pack.xsd">
    <body name="张三" age="14">
        <constructor-arg index="1" />
    </body>

    <pack:bag>
        <pack:front>
            <pack:name>card</pack:name>
        </pack:front>
        <pack:back>
            <pack:one>phone</pack:one>
            <pack:two>pad</pack:two>
            <pack:three>mac</pack:three>
        </pack:back>
    </pack:bag>
</person>
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值