XML Schema学习

发布时间 2023-04-24 16:22:45作者: kalixcn

XML Schema简介

XML Schena的作用是定义XML文档的划分构建模块。XML Schema是基于XML的DTD代替者,XML Schema可描述XML文档的结构。

  • 定义可出现在文档中的元素
  • 定义可出现在文档中的属性
  • 定义那个元素是子元素
  • 定义子元素的次序
  • 定义子元素的数目
  • 定义元素是否为空,或者是否包含文本
  • 定义元素的属性的数据类型
  • 定义元素和属性的默认值以及固定值

XML文档可对DTD或者XML Schema进行引用。
一个简单的XML文档:

<?xml version="1.0"?>
<note>
  <to>Tove</to>
  <from>Jani</from>
  <heading>Reminder</heading>
  <body>Don't forget me this weekend!</body>
</note>

DTD文件,对上面的XML文档的元素进行定义:

<!ELEMENT note (to,from,heading,body)>
<!ELEMENT t0 (#PCDATA)>
<!ELEMENT from (#PCDATA)>
<!ELEMENT heading (#PCDATA)>
<!ELEMENT body (#PCDATA)>

第一行定义node元素由四个子元素:"to、from、heading、body"。
第2-5行定义了to、from、heading、body元素的类型是"#PCDATA".
XML Schema文件,对上面的XML文档进行定义:

<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.w3schools.com"
xmlns="http://www.w3schools.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> 

对DTD的引用

 <?xml version="1.0"?>

<!DOCTYPE note SYSTEM
"http://www.w3schools.com/dtd/note.dtd">

<note>
  <to>Tove</to>
  <from>Jani</from>
  <heading>Reminder</heading>
  <body>Don't forget me this weekend!</body>
</note>

对XML Schema的引用

<?xml version="1.0"?>

<note
xmlns="http://www.w3schools.com"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.w3schools.com note.xsd">
  <to>Tove</to>
  <from>Jani</from>
  <heading>Reminder</heading>
  <body>Don't forget me this weekend!</body>
</note>

<schema>元素是每一个XML Schema的根元素:

<?xml version="1.0"?>
<xs:schema>
...
...
</xs:schema>

<schema>元素可包含属性。一个schema声明看上去类似下面这样:

<?xml version="1.0">
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.runoob.com" 
xmlns="http://www.runoob.com"
elementFormDefault="qualified">
...
...
</xs:schema>
xmlns:xs="http://www.w3.org/2001/XMLSchema"

显示schema中用到的元素和数据类型来自命名空间"http://www.w3.org/2001/XMLSchema",同时它还规定了来自命名空间"http://www.w3/org/2001/XMLSchema"的元素和数据类型应该使用前缀xs:
targetNamespace="http://www.runoob.com"

显示被此schema定义的元素(note,to,from,heading,body)来自命名空间:"http://www.runoob.com"
xmlns="http://www.runoob.com"

指出默认命名空间是"http://www.runoob.com"
elementFormDefault="qualified"

指出任何XML实例文档所使用的且在此schema中声明过的元素必须被命名空间限制

在XML文档中引用Schema

<?xml version="1.0"?>

<note xmlns="http://www.runoob.com"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.runoob.com note.xsd">

<to>Tove</to>
<from>Jani</from>
<heading>Reminder</heading>
<body>Don't forget me this weekend!</body>
</note> 
xmlns="http://www.runoob.com"

规定了默认命名空间的声明,此声明会告知schema验证器,在此XML文档中使用的所有元素都被声明于"http://www.runoob.com"这个命名空间。
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.runoob.com note.xsd"

XSD简易元素指那些只包含文本的元素。它不会包含任何其他的元素或属性。
定义简易元素的语法:

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

xxx指元素的名称,yyy指元素的数据类型。XML Schema拥有很多内建的数据类型。

最常用的类型是:

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

实例
这是一些XML元素:

<lastname>Refsnes</lastname>
<age>36</age>
<dateeborn>1970-03-27</dateborn>

这是相应的简易元素定义:

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

简易元素的默认值和固定值,当没有其他被规定时,默认就会自动分配给元素。

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

默认值是"red"

<xs:element name="color" type="xs:string" fixed="red"/>
固定值同样会自动分配给元素,并且你无法规定另外一个值。固定值是"red"

XSD属性,所有的属性都被作为简易类型来声明
定义属性语法是

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

xxx指属性名称,yyy则规定属性的数据类型

实例
这是带有属性的XML元素:

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

这是对应的属性定义:

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

属性的默认值和固定值
当没有其他的指被规定时,默认值会自动分配给元素。

<xs:attribute name="lang" type="xs:string" default="EN"/>
默认值是:EN

固定值同样会自动分配给元素,并且你无法规定另外的值

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

可选的和必需的属性
在默认情况下,属性是可选的。如需规定属性为必须的,请使用"use"属性:

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

XSD限定,限定(restriction)用于为XML元素或者属性定义可接收的值,对XML元素的限定被称为facet。

  1. 对值的限定,定义一个带有限定并且名为"age"的元素。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> 
  1. 对一组值的限定:定义一个Car的元素,其可接收的值只有:Audi,Golf,BMW:
<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> 
或者写成:
<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> 
  1. 对一系列值的限定:定义一个名为"letter"的元素,可接受的值只有小写字母a~z其中的一个:
<xs:element name="letter">
    <xs:simpleType>
        <xs:restriction base="xs:string">
            <xs:pattern value="[a-z]"/>
        </xs:restriction>
    </xs:simpleType>
</xs:element>

对应一个名为"initials"的元素,可接受的值是大写字母A-Z其中的三个:

<xs:element name="initials">
    <xs:simpleType>
        <xs:restriction base="xs:string">
            <xs:pattern value="[A-Z][A-Z][A-Z]"/>
        </xs:restriction>
    </xs:simpleType>
</xs:element>

定义一个名为"initals"的元素:可以接受的值是大写或者小写字母a-z其中的三个:

<xs:element name="initials">
    <xs:simpleType>
        <xs:restriction base="xs:string">
            <xs:pattern value="[a-zA-Z][a-zA-Z][a-zA-Z]">
        </xs:restriction>
    </xs:simpleType>
</xs:element>

定义一个名为"Choice"的元素,可以接受的值是字母x,y,z其中的一个:

<xs:element name="choice">
    <xs:simpleType>
        <xs:restriction base="xs:string">
            <xs:pattern value="[xyz]"/>
        </xs:restriction>
    </xs:simpleType>
</xs:element>

打印一个名为"prodid"的元素,可以接受的值是五个阿拉伯数字:

<xs:element name="prodid">
    <xs:simpleType>
        <xs:restriction base="xs:integer">
            <xs:pattern value="[0-9][0-9][0-9][0-9][0-9]"/>
        </xs:restriction>
    </xs:simpleType>
</xs:element>
  1. 对一系列值的其他限定
    定义一个名为"letter"的元素,可接受的值是a-z中的零个或者多个字母:
<xs:element name="letter">
    <xs:simpleType>
        <xs:restriction base="xs:string">
            <xs:pattern value="([a-z])*/>
        </xs:restriction>
    </xs:simpleType>
</xs:element>

定义一个名为"letter"的元素,其可以接受的值是一对或者多对字母,每对字母由一个小写字母后跟一个大写字母组成,举一个例子,"sToP"将会通过这种模式的验证,但是"Stop","STOP"或者"stop"无法通过验证:

<xs:element name="letter">
    <xs:simpleType>
        <xs:restriction base="xs:string">
            <xs:pattern value="([a-z][A-Z])+/">
        </xs:restriction>
    </xs:simpleType>
</xs:element>

定义一个名为"gender"的元素,其可以接受的值是male或者female:

<xs:element name="gender">
    <xs:simpleType>
        <xs:restriction base="xs:string">
            <xs:pattern value="male|female">
        </xs:restriction>
    </xs:simpleType>
</xs:element>

定义一个名为"password"的元素,其可以接受的值是由8个字符组成的一行字符,这些字符必须是大写或者小写字母a-z亦或者数字0-9:

<xs:element name="password">
    <xs:simpleType>
        <xs:restriction base="xs:string">
            <xs:pattern value="[a-zA-Z0-9]{8}"/>
        </xs:restriction>
    </xs:simpleType>
</xs:element>

对空白字符的限定,whiteSpace限定设置为"preserve",这意味着XML处理器不会移除任何空白字符:

<xs:element name="address">
    <xs:simpleType>
        <xs:restriction base="xs:string">
            <xs:whiteSpace value="preserve"/>
        </xs:restriction>
    </xs:simpleType>
</xs:element>

whiteSpace限定设置为"replace",这意味着XML处理器将移除所有的空白字符(换行、回车、空格以及制表符):

<xs:element name="address">
    <xs:simpleType>
        <xs:restriction base="xs:string">
            <xs:whiteSpace value="replace"/>
        </xs:restriction>
    </xs:simpleType>
</xs:element>

whiteSpace限定设置为"collapse",这意味着XML处理器将移除所有空白字符(换行、回车、空格以及制表符会被替换为空格,开头和结尾的空格会被移除,而多给连续的空格会被缩减为一个单一空格):

<xs:element name="address">
    <xs:simpleType>
        <xs:restriction base="xs:string">
            <xs:whiteSpace value="collapse"/>
        </xs:restriction>
    </xs:simpleType>
</xs:element>

对长度的限定,如果需要限制元素中的长度,我们需要使用length、maxLength以及minLength限定。
定义一个名为"password"的元素,其值必须精确到8个字符:

<xs:element name="password">
    <xs:simpleType>
        <xs:restriction base="xs:string">
            <xs:length value="8">
        </xs:restriction>
    </xs:simpleType>
</xs:element>

定义一个名为"password"的元素。其值最小为5个字符,最大为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>

数据类型的限定

限定 描述
enumeration 定义可接受值的一个列表
fractionDigits 定义所允许的最大的小数位数。必须大于等于0。
length 定义所允许的字符或者列表项目的精确数目。必须大于或等于0。
maxExclusive 定义数值的上限。所允许的值必须小于此值。
maxInclusive 定义数值的上限。所允许的值必须小于或等于此值。
maxLength 定义所允许的字符或者列表项目的最大数目。必须大于或等于0。
minExclusive 定义数值的下限。所允许的值必需大于此值。
minInclusive 定义数值的下限。所允许的值必需大于或等于此值
minLength 定义所允许的字符或者列表项目的最小数目。必须大于或等于0。
pattern 定义可接受的字符的精确序列。
totalDigits 定义所允许的阿拉伯数字的精确位数。必须大于0。
whiteSpace 定义空白字符(换行、回车、空格以及制表符)的处理方式。

XSD复合元素,复合元素指包含其他元素及/或者属性的XML元素。
四种类型的复合元素

  • 空元素
  • 包含其他元素的元素
  • 仅包含文本的元素
  • 包含元素的文本的元素
    复合元素的例子
  1. 复合元素,"product",是空的:
    <product pid="1345"/>
  2. 复合元素,"employee",仅包含其他元素:
<employee>
    <firestname>John</firestname>
    <lastname>Smith</lastname>
</employee>
  1. 复合XML元素,"food",仅包含文本:
    <food type="dessert">Ice cream</food>

定义复合元素:
在XML Schema中,有两种方式定义复合元素:

  1. 通过命名此元素,可直接对"employyee"元素进行声明
<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>

"firstname"以及"lastname",被包围在指示器<sequence>中,这意味着子元素必须以它们声明的次序出现。
  1. "employee"元素可以使用type属性,这个属性的作用是引用要使用的复合类型的名称:
<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>

如果使用了上面所描述的方法,那么若干元素均可使用相同的复合类型

<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>

也可以在已有的复合元素之上以某个复合元素为基础,然后添加一些元素,例如:

<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:complexTypee>

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

复合空元素
一个空的XML元素:
<product prodid="1345"/>

<xs:element name="product">
  <xs:complexType>
    <xs:complexContent>
      <xs:restriction base="xs:integer">
        <xs:attribute name="prodid" type="xs:positiveInteger"/>
      </xs:restriction>
    </xs:complexContent>
  </xs:complexType>
</xs:element> 

XSD仅含元素,"仅含元素"的复合类型元素是只能包含其他元素的元素。
XML元素,"person",仅包含其他的元素:

<person>
    <firestname>John</firestname>
    <lastname>Smith</lastname>
</person>

可以在schema中这样定义"person"元素:

<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:complexType>
</xs:element>
或者
<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元素,"letter",含有文本以及其他元素:

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

schema声明这个"letter"元素:

<xs:element name="letter">
    <xs:complerType 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:complerType>
</xs:element>

注意: 为了使字符数据可以出现在 "letter" 的子元素之间,mixed 属性必须被设置为 "true"。<xs:sequence> 标签 (name、orderid 以及 shipdate ) 意味着被定义的元素必须依次出现在 "letter" 元素内部。
也可以为complexType元素起一个名字,并让"letter"元素的type属性引用complexType的这个名称(通过这个方法,若干元素均可引用同一个复合类型):

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

XSD指示器
Order指示器:

  • ALL
  • Choice
  • Sequence

Occurrence指示器:

  • maxOccurs
  • minOccurs

Group指示器:

  • Group name
  • attributeGroup name

Order指示器用于定义元素的顺序
<all>指示器规定子元素可以安装任意顺序出现,并且每个子元素必须只出现一次:

<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>

注意:当使用<all>指示器时,你可以把<minOccurs>设置为0或者1,而只能把<maxOccurs>指示器设置为1。
Choice指示器规定可出现某个子元素或者出现另外一个子元素(非此即彼):

<xs:element name="person">
    <xs:complexType>
        <xs:choice>
            <xs:element name="employee" type="employee">
            <xs:element name="member" type="member">
        </xs:choice>
    </xs:complexType>
</xs:element>

Sequence指示器
<sequence>规定子元素必须按照特定的顺序出现:

<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:complexType>
</xs:element>

Occurrence指示器用于定义某个元素出现的频率。<maxOccurs>指示器可规定某个元素可出现的最大次数,<minOccurs> 指示器可规定某个元素能够出现的最小次数:

<xs:element name="pesron">
    <xs:complexType>
        <xs:sequence>
            <xs:element name="full_name" type="xs:string">
            <xs:element name="child_nmae" type="xs:string" maxOccurs="10"/>
        </xs:sequence>
    </xs:complexType>
</xs:element>
<xs:element name="person">
    <xs:complexType>
        <xs:sequence>
            <xs:element name="full_name" type="xs:string">
            <xs:element name="child_nam" type="xs:string" maxOccurs="10" minOccurs="0">
        </xs:sequence>
    </xs:complexType>
</xs:element>

在上面的例子中,子元素"child_name"可在"person"元素中出现最少0次,最多出现10次。
提示:如需时某一个元素的出现次数不受限制,请使用max0ccurs="unbounded"这个声明:
实例:
XML文件

<?xml version="1.0" encoding="ISO-8859-1"?>

<persons xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="family.xsd">

<person>
  <full_name>Hege Refsnes</full_name>
  <child_name>Cecilie</child_name>
</person>

<person>
  <full_name>Tove Refsnes</full_name>
  <child_name>Hege</child_name>
  <child_name>Stale</child_name>
  <child_name>Jim</child_name>
  <child_name>Borge</child_name>
</person>

<person>
  <full_name>Stale Refsnes</full_name>
</person>

</persons> 

schema文件

<?xml version="1.0" encoding="ISO-8859-1"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified">

<xs:element name="persons">
  <xs:complexType>
    <xs:sequence>
      <xs:element name="person" maxOccurs="unbounded">
        <xs:complexType>
          <xs:sequence>
            <xs:element name="full_name" type="xs:string"/>
            <xs:element name="child_name" type="xs:string"
            minOccurs="0" maxOccurs="5"/>
          </xs:sequence>
        </xs:complexType>
      </xs:element>
    </xs:sequence>
  </xs:complexType>
</xs:element>

</xs:schema> 

<any>元素使我们有能力通过未被schema规定的元素来拓展XML文档:

<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> 

<anyAttribute>元素使我们有能力通过未被schema规定的属性来扩展XML文档
通过使用\ 元素,我们就可以向 "person" 元素添加任意数量的属性:

<xs:element name="pesron">
    <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>

元素替换
我们可以在XML schema中定义一个substitutionGroup,首先,我们先声明主元素,然后我们会声明次元素,这些次元素可以声明它们能够替换主元素。

<xs:element name="name" type="xs:string"/>
<xs:element name="navn" substitutionGroup="name"/>

"nmae"元素是主元素,而"navn"元素可替换"name"元素。
为防止其他元素替换某个指定的元素,请使用block属性:

<xs:element name="name" type="xs:string" block="substitution"/>

使用 substitutionGroup
可替换元素的类型必须和主元素相同,或者从主元素衍生而来。假如可替换元素的类型与主元素的类型相同,那么您就不必规定可替换元素的类型了。
请注意,substitutionGroup 中的所有元素(主元素和可替换元素)必须被声明为全局元素,否则就无法工作!
全局元素指"schema"元素的直接子元素,本地元素值嵌套在其他元素中的元素。

XSD字符串数据类型
字符串数据类型用于可包含字符串的值。字符串数据类型可包含字符、换行、回车以及制表符。

<xs:element name="customer" type="xs:string">

注意:如果使用字符串类型,XML处理器就不会更改其中的值。

规格化字符串数据类型(NormalizedString Date Type)
规格化字符串数据类型源自于字符串数据类型,规格化字符串数据类型同样可包好字符,但是XML处理器会移除折行、回车以及制表符。

<xs:element name="customer" type="xs:normalizedString"/>

Token数据类型(Token Data Type)
Token数据类型同样源自于字符串数据类型。Token数据类型同样可包含字符,但是XML处理器会移除换行符、回车、制表符、开头和结尾的空格以及(连续的)空格。

<xs:element name="customer" typer="xs:token"/>

学习网址