Xml schema - littleboy12580/learning_python GitHub Wiki

XSD简介

XML Schema,又常被称为XSD(XML Schema Definition);它是用来描述 XML 文档的结构,是DTD的代替;它有如下功能:

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

XSD基础

  1. Xml Schema也是一个xml文件,其扩展名通常为.xsd。
  2. XSD中必须定义一个且只能定义一个schema根元素,根元素中包括模式的约束,XML模式命名空间的定义,其他命名空间的定义、版本信息、语言信息和其他一些信息
  3. 一个Xml Schema,通常称为模式文档(约束文档),遵循这个文档写的xml称之为实例文档。
  4. 编写一个约束文档后,通常需要把则个文件中声明的元素绑定到一个URI地址上,即定义为一个命名空间,以后xml文件就可以通过这个URI(命名空间)来告诉解析引擎,xml文档中编写的元素来自哪里,被谁约束

XSD声明

下面代码显示了一个常见的XSD声明

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

...
...
</xs:schema>
  1. xmlns:引入命名空间(namespace):默认是W3C的。这个默认引用,只能出现一次。非默认引用需要加别名:如xmlns:xs="http://www.w3.org/2001/XMLSchema",增加了别名 xs 。一个文档可以引入多个命名空间。
  2. targetNamespace:定义命名空间,其实Xml Schema的本质就是定义一个命名空间,共其他Xml引用。这边的命名空间定义为URI为 "http://www.w3school.com.cn" ,引用的时候也必须是这个
  3. elementFormDefault:控制元素。有两个取值:"qualified"-定义的所有元素都绑定为这个命名空间; unqualified:表示只有根元素绑定为这个命名空间

如果一个xml文件想要引用这个xml schema,则可以有如下代码:

<?xml version="1.0"?>

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

<to>George</to>
<from>John</from>
<heading>Reminder</heading>
<body>Don't forget the meeting!</body>
</note>
  1. xmlns:引入命名空间约束 ,只是虚的路径,需要 schemaLocation具体指定位置
  2. 使用xmlns:xsi指定为来自的命名空间为 W3C,固定用法
  3. schemaLocation:辅助xmlns引入“实”的命名空间,指定具体的命名空间所指向的文件,需要具体路径。2部分组成:定义好的命名空间路径 + 具体schema文件的路径

XSD语法

简单类型simpleType

简易元素指那些仅包含文本的元素。它不会包含任何其他的元素或属性;此处“仅包含文本”里的“文本”有很多类型;它可以是 XML Schema 定义中包括的类型中的一种(布尔、字符串、数据等等),或者它也可以是您自行定义的定制类型。
可以向数据类型添加限定(即 facets),以此来限制它的内容,也可以要求数据匹配某种特定的模式

简单元素

定义简易元素的语法:element 关键字

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

此处 xxx 指元素的名称,yyy 指元素的数据类型。XML Schema 拥有很多内建的数据类型,下面是一些最常用的数据类型

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

简易元素可拥有指定的默认值或固定值。当没有其他的值被规定时,默认值就会自动分配给元素;而如果被设置成了固定值,则无法再被更改

<xs:element name="color" type="xs:string" default="red"/>               #默认值
<xs:element name="color" type="xs:string" fixed="red"/>                   #固定值

属性

所有的属性均作为简易类型来声明;简易元素无法拥有属性。假如某个元素拥有属性,它就会被当作某种复合类型;但是属性本身总是作为简易类型被声明的
定义属性的语法:attrribute 关键字

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

xxx 指属性名称,yyy 则规定属性的数据类型;XML Schema 拥有很多内建的数据类型;下面是一些最常用的类型:

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

属性同样拥有缺省值与固定值

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

在缺省的情况下,属性是可选的。如需规定属性为必选,可以使用 "use" 属性:

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

限定

限定(restriction)用于为 XML 元素或者属性定义可接受的值。对 XML 元素的限定被称为 facet
一些常用数据类型限定如下:

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

以下是一些实例

<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> 
<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="letter">

<xs:simpleType>
  <xs:restriction base="xs:string">
    <xs:pattern value="([a-z])*"/>
  </xs:restriction>
</xs:simpleType>

</xs:element> 
<xs:element name="address">

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

</xs:element> 

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

复杂类型complexType

复合元素指包含其他元素及/或属性的 XML 元素;有四种类型的复合元素:

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

注释:上述元素均可包含属性

复合元素的定义

假设存在如下复合xml元素employee,可以通过如下方式对其进行定义:

  • 通过命名此元素,可直接对"employee"元素进行声明
<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" 元素可以使用 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="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>

复合空元素

复合元素不能包含内容,只能含有属性

<product prodid="1345" />  

上面的 "product" 元素根本没有内容。为了定义无内容的类型,我们就必须声明一个在其内容中只能包含元素的类型,但是实际上我们并不会声明任何元素,例如

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

complexContent 元素给出的信号是,我们打算限定或者拓展某个复合类型的内容模型,而 integer 限定则声明了一个属性但不会引入任何的元素内容;也可以使用以下写法(推荐)

<xs:element name="product" type="prodtype"/>

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

仅含元素

“仅含元素”的复合类型元素是只能包含其他元素的元素;实例如下:

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

仅含文本

此类型仅包含简易的内容(文本和属性),因此我们要向此内容添加 simpleContent 元素。当使用简易内容时,我们就必须在 simpleContent 元素内定义扩展或限定,例如:

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

则可以使用以下schema来描述:

<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" 的子元素之间,mixed 属性必须被设置为 "true";xs:sequence 标签 (name、orderid 以及 shipdate ) 意味着被定义的元素必须依次出现在 "letter" 元素内部。

指示器

通过指示器,我们可以控制在文档中使用元素的方式。有七种指示器(前五种常用):

  • Order 指示器:
    • All
    • Choice
    • Sequence
  • Occurrence 指示器:
    • maxOccurs
    • minOccurs
  • Group 指示器:
    • Group name
    • attributeGroup name

Order 指示器

Order 指示器用于定义元素的顺序

  • 指示器规定子元素可以按照任意顺序出现,且每个子元素必须只出现一次(当使用 指示器时,你可以把 设置为 0 或者 1,而只能把 指示器设置为 1)
  • 指示器规定可出现某个子元素或者可出现另外一个子元素(非此即彼)
  • 规定子元素必须按照特定的顺序出现

Occurrence 指示器

用于定义某个元素出现的频率

  • 指示器可规定某个元素可出现的最大次数
  • 指示器可规定某个元素能够出现的最小次数
  • 如需使某个元素的出现次数不受限制,可以使用 maxOccurs="unbounded"

Group 指示器

Group 指示器用于定义相关的数批元素

  • 元素组通过 group 声明进行定义
  • 属性组通过 attributeGroup 声明来进行定义
  • 必须在 group 声明内部定义一个 all、choice 或者 sequence 元素
  • 在把 group 定义完毕以后,就可以在另一个定义中引用它了

下面是一个实例:

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

文档扩展

和 均可用于制作可扩展的文档!它们使文档有能力包含未在主 XML schema 中声明过的附加元素;具体实例如下:

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

这是一个名为 "family.xsd" 的 XML schema

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

<xs:element name="children">
  <xs:complexType>
    <xs:sequence>
      <xs:element name="childname" type="xs:string"
      maxOccurs="unbounded"/>
    </xs:sequence>
  </xs:complexType>
</xs:element>

</xs:schema>

这是一个名为"children.xsd"的XML schema

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

<persons xmlns="http://www.microsoft.com"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:SchemaLocation="http://www.microsoft.com family.xsd
http://www.w3school.com.cn children.xsd">

<person>
<firstname>David</firstname>
<lastname>Smith</lastname>
<children>
  <childname>mike</childname>
</children>
</person>

<person>
<firstname>Tony</firstname>
<lastname>Smith</lastname>
</person>

</persons>

该xml文档使用了来自两个不同的 schema 中的成分,"family.xsd" 和 "children.xsd",是合法的
元素也是一样的用法

XSD数据类型

字符串

字符串的数据类型表如下所示:

请注意,所有以下的数据类型均衍生于字符串数据类型(除了字符串数据类型本身)!

名称 描述
ENTITIES  
ENTITY  
ID 在 XML 中提交 ID 属性的字符串 (仅与 schema 属性一同使用)
IDREF 在 XML 中提交 IDREF 属性的字符串(仅与 schema 属性一同使用)
IDREFS language 包含合法的语言 id 的字符串
Name 包含合法 XML 名称的字符串
NCName  
NMTOKEN 在 XML 中提交 NMTOKEN 属性的字符串 (仅与 schema 属性一同使用)
NMTOKENS  
normalizedString 不包含换行符、回车或制表符的字符串
QName  
string 字符串
token 不包含换行符、回车或制表符、开头或结尾空格或者多个连续空格的字符串

对字符串类型的限定如下所示:

  • enumeration
  • length
  • maxLength
  • minLength
  • pattern (NMTOKENS、IDREFS 以及 ENTITIES 无法使用此约束)
  • whiteSpace

日期与时间

日期与时间的数据类型表如下所示:

名称 描述
date 定义一个日期值
dateTime 定义一个日期和时间值
duration 定义一个时间间隔
gDay 定义日期的一个部分 - 天 (DD)
gMonth 定义日期的一个部分 - 月 (MM)
gMonthDay 定义日期的一个部分 - 月和天 (MM-DD)
gYear 定义日期的一个部分 - 年 (YYYY)
gYearMonth 定义日期的一个部分 - 年和月 (YYYY-MM)
time 定义一个时间值

对日期与时间的限定如下所示:

  • enumeration
  • maxExclusive
  • maxInclusive
  • minExclusive
  • minInclusive
  • pattern
  • whiteSpace

数值

数值的数据类型表如下所示:

请注意,下面所有的数据类型均源自于十进制数据类型(除 decimal 本身以外)!

名字 秒数
byte 有正负的 8 位整数
decimal 十进制数
int 有正负的 32 位整数
integer 整数值
long 有正负的 64 位整数
negativeInteger 仅包含负值的整数 ( .., -2, -1.)
nonNegativeInteger 仅包含非负值的整数 (0, 1, 2, ..)
nonPositiveInteger 仅包含非正值的整数 (.., -2, -1, 0)
positiveInteger 仅包含正值的整数 (1, 2, ..)
short 有正负的 16 位整数
unsignedLong 无正负的 64 位整数
unsignedInt 无正负的 32 位整数
unsignedShort 无正负的 16 位整数
unsignedByte 无正负的 8 位整数

对数值的限定如下所示:

  • enumeration
  • fractionDigits
  • maxExclusive
  • maxInclusive
  • minExclusive
  • minInclusive
  • pattern
  • totalDigits
  • whiteSpace

杂项

杂项的数据类型表如下所示:

名称 描述
anyURI  
base64Binary  
boolean  
double  
float  
hexBinary  
NOTATION  
QName  

对杂项的限定如下所示:

  • enumeration (布尔数据类型无法使用此约束*)
  • length (布尔数据类型无法使用此约束)
  • maxLength (布尔数据类型无法使用此约束)
  • minLength (布尔数据类型无法使用此约束)
  • pattern
  • whiteSpace
⚠️ **GitHub.com Fallback** ⚠️