Web

xsd

Posted by Kerwen Blog on December 26, 2024

XML Schema 描述XML文档的结构。

XML模式的目的是定义XML文档的合法构建块:

  • 可以出现在文档中的元素和属性
  • 子元素的数量(和顺序)
  • 元素和属性的数据类型
  • 元素和属性的默认值和固定值

下面是一个名为”note.xml”的简单XML文档:

1
2
3
4
5
6
7
<?xml version="1.0"?>
<note>
  <to>Tove</to>
  <from>Jani</from>
  <heading>Reminder</heading>
  <body>Don't forget me this weekend!</body>
</note>

下面的实例是一个名为”note.xsd”的XML模式文件,它定义了上述XML文档的元素(”note.xml”):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="https://www.w3ccoo.com"
xmlns="https://www.w3ccoo.com"
elementFormDefault="qualified">

<xs:element name="note">
  <xs:complexType>
    <xs:sequence>
      <xs:element name="to" type="xs:string"/>
      <xs:element name="from" type="xs:string"/>
      <xs:element name="heading" type="xs:string"/>
      <xs:element name="body" type="xs:string"/>
    </xs:sequence>
  </xs:complexType>
</xs:element>

</xs:schema>

note元素是复杂类型,因为它包含其他元素。其他元素(to、from、heading、body)是简单类型,因为它们不包含其他元素。在下面的章节中,您将了解有关简单类型和复杂类型的更多信息。

schema

<schema> 元素是每个XML模式的根元素。

1
2
3
4
5
6
<?xml version="1.0"?>

<xs:schema>
...
...
</xs:schema>

<schema> 元素通常包含一些属性:

1
2
3
4
5
6
7
8
9
<?xml version="1.0"?>

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="https://www.w3ccoo.com"
xmlns="https://www.w3ccoo.com"
elementFormDefault="qualified">
...
...
</xs:schema>
  • xmlns:xs 指示架构中使用的元素和数据类型来自”http://www.w3.org/2001/XMLSchema”命名空间。 它还指定来自”http://www.w3.org/2001/XMLSchema” 命名空间应以xs作为前缀;
  • targetNamespace指示此架构定义的元素(注释、收件人、发件人、标题、正文)来自”https://www.w3ccoo.com”命名空间。
  • xmlns指示默认命名空间
  • elementFormDefault指示在此架构中声明的XML实例文档所使用的任何元素都必须是命名空间限定的。

元素

简单元素

简单元素是只能包含文本的XML元素。它不能包含任何其他元素或属性。
然而,只能包含文本的限制却相当具有误导性。文本可以有许多不同的类型。它可以是XML模式定义中包含的类型之一(boolean、string、date等),也可以是您自己定义的自定义类型。
定义简单元素的语法为:

1
<xs:element name="xxx" type="yyy"/>

其中xxx是元素的名称,yyy是元素的数据类型。
XML Schema 有很多内置的数据类型。最常见的类型有:

  • xs:string
  • xs:decimal
  • xs:integer
  • xs:boolean
  • xs:date
  • xs:time

以下是一些XML元素:

1
2
3
<lastname>Refsnes</lastname>
<age>36</age>
<dateborn>1970-03-27</dateborn>

下面是相应的简单元素定义:

1
2
3
<xs:element name="lastname" type="xs:string"/>
<xs:element name="age" type="xs:integer"/>
<xs:element name="dateborn" type="xs:date"/>

简单元素的默认值和固定值

简单元素可以指定默认值或固定值。
当未指定其他值时,将自动为元素指定默认值。
在以下实例中,默认值为 “red”:

1
<xs:element name="color" type="xs:string" default="red"/>

固定值也会自动指定给元素,并且不能指定其他值。
在以下实例中,固定值为红色 “red”:

1
<xs:element name="color" type="xs:string" fixed="red"/>

属性

所有属性都声明为简单类型。
简单元素不能有属性。如果一个元素有属性,它被认为是一个复杂的类型。但是属性本身总是声明为简单类型。
定义属性的语法是:

1
<xs:attribute name="xxx" type="yyy"/>

其中xxx是属性的名称,yyy指定属性的数据类型。
下面是一个带有属性的XML元素:

1
<lastname lang="EN">Smith</lastname>

下面是相应的属性定义:

1
<xs:attribute name="lang" type="xs:string"/>

默认值和固定值

属性可以指定默认值或固定值。
如果未指定其他值,则会自动为属性指定默认值。

在以下实例中,默认值为 “EN”:

1
<xs:attribute name="lang" type="xs:string" default="EN"/>

固定值也会自动指定给属性,并且不能指定其他值。
在以下实例中,固定值为 “EN”:

1
<xs:attribute name="lang" type="xs:string" fixed="EN"/>

可选和必需属性

默认情况下,属性是可选的。要指定属性是必需的,请使用”use”属性:

1
2
3
4
5
6
7
8
9
10
<xs:attribute name="lang" type="xs:string" use="required"/> ## 限制restriction  限制用于定义XML元素或属性的可接受值。   ### 对值的限制 下面的实例定义了一个名为"age"是有限制的,年龄值不能小于0或大于120:

<xs:element name="age">
  <xs:simpleType>
    <xs:restriction base="xs:integer">
      <xs:minInclusive value="0"/>
      <xs:maxInclusive value="120"/>
    </xs:restriction>
  </xs:simpleType>
</xs:element>

对一组值的限制

为了将XML元素的内容限制为一组可接受的值,我们将使用枚举约束。

下面的实例定义了一个名为&quot;汽车;有限制的。唯一可接受的数值是:奥迪、高尔夫、宝马:

1
2
3
4
5
6
7
8
9
<xs:element name="car">
  <xs:simpleType>
    <xs:restriction base="xs:string">
      <xs:enumeration value="Audi"/>
      <xs:enumeration value="Golf"/>
      <xs:enumeration value="BMW"/>
    </xs:restriction>
  </xs:simpleType>
</xs:element>

上面的例子也可以这样写:

1
2
3
4
5
6
7
8
9
<xs:element name="car" type="carType"/>

<xs:simpleType name="carType">
  <xs:restriction base="xs:string">
    <xs:enumeration value="Audi"/>
    <xs:enumeration value="Golf"/>
    <xs:enumeration value="BMW"/>
  </xs:restriction>
</xs:simpleType>

在这种情况下,”carType”类型可以被其他元素使用,因为它不是”car”元素的一部分。

对一系列值的限制

为了限制XML元素的内容来定义一系列可以使用的数字或字母,我们将使用模式约束。
下面的实例定义了一个名为”letter”的元素,其中包含一个限制。唯一可接受的值是从a到z的小写字母之一:

1
2
3
4
5
6
7
<xs:element name="letter">
  <xs:simpleType>
    <xs:restriction base="xs:string">
      <xs:pattern value="[a-z]"/>
    </xs:restriction>
  </xs:simpleType>
</xs:element>

下面的实例定义了一个名为”letter”的元素,其中包含一个限制。可接受的值是从a到z的小写字母出现次数为零或更多:

1
2
3
4
5
6
7
<xs:element name="letter">
  <xs:simpleType>
    <xs:restriction base="xs:string">
      <xs:pattern value="([a-z])*"/>
    </xs:restriction>
  </xs:simpleType>
</xs:element>

对空白字符的限制

要指定如何处理空白字符,我们将使用空白约束。
本例定义了一个名为”address”的元素,其中包含一个限制。空白约束设置为”preserve”,这意味着XML处理器不会删除任何空白字符:

1
2
3
4
5
6
7
<xs:element name="address">
  <xs:simpleType>
    <xs:restriction base="xs:string">
      <xs:whiteSpace value="preserve"/>
    </xs:restriction>
  </xs:simpleType>
</xs:element>

空白约束可以设置为:

  • preserve 不会删除任何空白字符;
  • replace 用空格替换所有空白字符(换行符、制表符、空格和回车);
  • collapse 删除所有空格字符(换行符、制表符、空格、回车替换为空格,删除前导空格和尾随空格,并将多个空格缩减为单个空格)

长度限制

为了限制元素中值的长度,我们将使用length、maxLength和minLength约束。
本例定义了一个名为”password”的元素,其中有一个限制。值必须正好是八个字符:

1
2
3
4
5
6
7
<xs:element name="password">
  <xs:simpleType>
    <xs:restriction base="xs:string">
      <xs:length value="8"/>
    </xs:restriction>
  </xs:simpleType>
</xs:element>

本例定义了另一个名为”password”的元素,其中有一个限制。值必须至少为五个字符,最多为八个字符:

1
2
3
4
5
6
7
8
<xs:element name="password">
  <xs:simpleType>
    <xs:restriction base="xs:string">
      <xs:minLength value="5"/>
      <xs:maxLength value="8"/>
    </xs:restriction>
  </xs:simpleType>
</xs:element>

复杂元素

复杂元素包含其他元素和/或属性。
有四种复杂元素:

  • 空元素
  • 只包含其他元素的元素
  • 仅包含文本的元素
  • 包含其他元素和文本的元素

我们可以用两种不同的方式在XML模式中定义复杂元素:

  1. 可以通过命名元素直接声明”employee”元素,如下所示:

    1
    2
    3
    4
    5
    6
    7
    8
    
     <xs:element name="employee">
       <xs:complexType>
         <xs:sequence>
           <xs:element name="firstname" type="xs:string"/>
           <xs:element name="lastname" type="xs:string"/>
         </xs:sequence>
       </xs:complexType>
     </xs:element>
    

    如果使用上述方法,则只有”employee”元素可以使用指定的复杂类型。注意,子元素”firstname”和”lastname”被指示符包围。这意味着子元素必须按照声明的顺序出现。

  2. “employee” 元素可以有一个type属性,该属性引用要使用的复杂类型的名称:

    1
    2
    3
    4
    5
    6
    7
    8
    
     <xs:element name="employee" type="personinfo"/>
    
     <xs:complexType name="personinfo">
       <xs:sequence>
         <xs:element name="firstname" type="xs:string"/>
         <xs:element name="lastname" type="xs:string"/>
       </xs:sequence>
     </xs:complexType>
    

    如果使用上述方法,则多个元素可以引用同一复杂类型,如下所示:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    
     <xs:element name="employee" type="personinfo"/>
     <xs:element name="student" type="personinfo"/>
     <xs:element name="member" type="personinfo"/>
    
     <xs:complexType name="personinfo">
       <xs:sequence>
         <xs:element name="firstname" type="xs:string"/>
         <xs:element name="lastname" type="xs:string"/>
       </xs:sequence>
     </xs:complexType>
    

也可以基于现有的复杂元素创建复杂元素并添加一些元素,如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<xs:element name="employee" type="fullpersoninfo"/>

<xs:complexType name="personinfo">
  <xs:sequence>
    <xs:element name="firstname" type="xs:string"/>
    <xs:element name="lastname" type="xs:string"/>
  </xs:sequence>
</xs:complexType>

<xs:complexType name="fullpersoninfo">
  <xs:complexContent>
    <xs:extension base="personinfo">
      <xs:sequence>
        <xs:element name="address" type="xs:string"/>
        <xs:element name="city" type="xs:string"/>
        <xs:element name="country" type="xs:string"/>
      </xs:sequence>
    </xs:extension>
  </xs:complexContent>
</xs:complexType>

空元素

空的复杂元素不能有内容,只能有属性。
空XML元素:

1
<product prodid="1345" />

声明”product”元素,如下所示

1
2
3
4
5
<xs:element name="product">
  <xs:complexType>
    <xs:attribute name="prodid" type="xs:positiveInteger"/>
  </xs:complexType>
</xs:element>

或者:

1
2
3
4
5
<xs:element name="product" type="prodtype"/>

<xs:complexType name="prodtype">
  <xs:attribute name="prodid" type="xs:positiveInteger"/>
</xs:complexType>

仅元素elements-only

XML元素”person”,它仅包含其他元素:

1
2
3
4
<person>
  <firstname>John</firstname>
  <lastname>Smith</lastname>
</person>

定义”person”元素,如下所示:

1
2
3
4
5
6
7
8
<xs:element name="person" type="persontype"/>

<xs:complexType name="persontype">
  <xs:sequence>
    <xs:element name="firstname" type="xs:string"/>
    <xs:element name="lastname" type="xs:string"/>
  </xs:sequence>
</xs:complexType>

纯文本元素

纯文本元素可以包含文本和属性。
以下是仅包含文本的XML元素”shoesize”的实例:

1
<shoesize country="france">35</shoesize>

下面的实例声明了一个纯文本复杂元素”shoesize”。内容定义为整数值,”shoesize”元素还包含一个名为”country”的属性:

1
2
3
4
5
6
7
8
9
<xs:element name="shoesize" type="shoetype"/>

<xs:complexType name="shoetype">
  <xs:simpleContent>
    <xs:extension base="xs:integer">
      <xs:attribute name="country" type="xs:string" />
    </xs:extension>
  </xs:simpleContent>
</xs:complexType>

混合内容

混合复杂类型元素可以包含属性、元素和文本。
包含文本和其他元素的XML元素”letter”:

1
2
3
4
5
<letter>
  Dear Mr. <name>John Smith</name>.
  Your order <orderid>1032</orderid>
  will be shipped on <shipdate>2001-07-13</shipdate>.
</letter>

以下架构声明”letter”元素:

1
2
3
4
5
6
7
8
9
<xs:element name="letter" type="lettertype"/>

<xs:complexType name="lettertype" mixed="true">
  <xs:sequence>
    <xs:element name="name" type="xs:string"/>
    <xs:element name="orderid" type="xs:positiveInteger"/>
    <xs:element name="shipdate" type="xs:date"/>
  </xs:sequence>
</xs:complexType>

要使字符数据出现在”letter”的子元素之间,混合属性必须设置为”true”。

指示器

我们可以控制元素在带有指示符的文档中的使用方式。
有七个指标符:

  • 顺序指示符:
    顺序指示符用于定义元素的顺序。
    • All: 指示符指定子元素可以以任何顺序出现,并且每个子元素只能出现一次

      1
      2
      3
      4
      5
      6
      7
      8
      
      <xs:element name="person">
        <xs:complexType>
          <xs:all>
            <xs:element name="firstname" type="xs:string"/>
            <xs:element name="lastname" type="xs:string"/>
          </xs:all>
        </xs:complexType>
      </xs:element>
      
    • Choice: 指定可以出现一个子元素或另一个子元素:
    • Sequence: 指定子元素必须按特定顺序出现:
  • 发生指示符:
    用于定义元素出现的频率。
    • maxOccurs: 定元素可以出现的最大次数, 如果要允许元素出现无限次,请使用maxOccurs=”unbounded”语句
    • minOccurs: 指定元素可以出现的最小次数

      1
      2
      3
      4
      5
      6
      7
      8
      9
      
      <xs:element name="person">
        <xs:complexType>
          <xs:sequence>
            <xs:element name="full_name" type="xs:string"/>
            <xs:element name="child_name" type="xs:string"
            maxOccurs="10" minOccurs="0"/>
          </xs:sequence>
        </xs:complexType>
      </xs:element>
      
  • 组指示符:
    组指示符用于定义相关的元素集。
    • Group name
      必须在组声明中定义all、choice或sequence元素。

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      
      <xs:group name="persongroup">
        <xs:sequence>
          <xs:element name="firstname" type="xs:string"/>
          <xs:element name="lastname" type="xs:string"/>
          <xs:element name="birthday" type="xs:date"/>
        </xs:sequence>
      </xs:group>
      
      <xs:element name="person" type="personinfo"/>
      
      <xs:complexType name="personinfo">
        <xs:sequence>
          <xs:group ref="persongroup"/>
          <xs:element name="country" type="xs:string"/>
        </xs:sequence>
      </xs:complexType>
      
    • attributeGroup name

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      
      <xs:attributeGroup name="personattrgroup">
        <xs:attribute name="firstname" type="xs:string"/>
        <xs:attribute name="lastname" type="xs:string"/>
        <xs:attribute name="birthday" type="xs:date"/>
      </xs:attributeGroup>
      
      <xs:element name="person">
        <xs:complexType>
          <xs:attributeGroup ref="personattrgroup"/>
        </xs:complexType>
      </xs:element>
      

any

any元素使我们能够用模式未指定的元素扩展XML文档。
下面的实例显示了”person”元素的声明。通过使用元素,我们可以用任何元素扩展"person"的内容:

1
2
3
4
5
6
7
8
9
<xs:element name="person">
  <xs:complexType>
    <xs:sequence>
      <xs:element name="firstname" type="xs:string"/>
      <xs:element name="lastname" type="xs:string"/>
      <xs:any minOccurs="0"/>
    </xs:sequence>
  </xs:complexType>
</xs:element>

“children”元素:

1
2
3
4
5
6
7
8
<xs:element name="children">
  <xs:complexType>
    <xs:sequence>
      <xs:element name="childname" type="xs:string"
      maxOccurs="unbounded"/>
    </xs:sequence>
  </xs:complexType>
</xs:element>

下面的XML文件(称为”Myfamily.xml”)使用来自两个不同模式的组件”family.xsd”和”children.xsd”:

1
2
3
4
5
6
7
8
9
10
11
12
<person>
  <firstname>Hege</firstname>
  <lastname>Refsnes</lastname>
  <children>
    <childname>Cecilie</childname>
  </children>
</person>

<person>
  <firstname>Stale</firstname>
  <lastname>Refsnes</lastname>
</person>

anyAttribute

anyAttribute使我们能够使用模式未指定的属性扩展XML文档。
下面的实例显示了”person”元素的声明。通过使用<anyAttribute>元素,我们可以向”person”元素添加任意数量的属性

1
2
3
4
5
6
7
8
9
<xs:element name="person">
  <xs:complexType>
    <xs:sequence>
      <xs:element name="firstname" type="xs:string"/>
      <xs:element name="lastname" type="xs:string"/>
    </xs:sequence>
    <xs:anyAttribute/>
  </xs:complexType>
</xs:element>

我们要用”eyecolor”属性扩展”person”元素。

1
2
3
4
5
6
7
<xs:attribute name="eyecolor">
  <xs:simpleType>
    <xs:restriction base="xs:string">
      <xs:pattern value="blue|brown|green|grey"/>
    </xs:restriction>
  </xs:simpleType>
</xs:attribute>

下面的XML文件使用来自两个不同模式的组件

1
2
3
4
5
6
7
8
9
<person eyecolor="green">
  <firstname>Hege</firstname>
  <lastname>Refsnes</lastname>
</person>

<person eyecolor="blue">
  <firstname>Stale</firstname>
  <lastname>Refsnes</lastname>
</person>

Reference: XML Schema 架构教程