Xml schema - littleboy12580/learning_python GitHub Wiki
XML Schema,又常被称为XSD(XML Schema Definition);它是用来描述 XML 文档的结构,是DTD的代替;它有如下功能:
- 定义可出现在文档中的元素
- 定义可出现在文档中的属性
- 定义哪个元素是子元素
- 定义子元素的次序
- 定义子元素的数目
- 定义元素是否为空,或者是否可包含文本
- 定义元素和属性的数据类型
- 定义元素和属性的默认值以及固定值
- Xml Schema也是一个xml文件,其扩展名通常为.xsd。
- XSD中必须定义一个且只能定义一个schema根元素,根元素中包括模式的约束,XML模式命名空间的定义,其他命名空间的定义、版本信息、语言信息和其他一些信息
- 一个Xml Schema,通常称为模式文档(约束文档),遵循这个文档写的xml称之为实例文档。
- 编写一个约束文档后,通常需要把则个文件中声明的元素绑定到一个URI地址上,即定义为一个命名空间,以后xml文件就可以通过这个URI(命名空间)来告诉解析引擎,xml文档中编写的元素来自哪里,被谁约束
下面代码显示了一个常见的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>
- xmlns:引入命名空间(namespace):默认是W3C的。这个默认引用,只能出现一次。非默认引用需要加别名:如xmlns:xs="http://www.w3.org/2001/XMLSchema",增加了别名 xs 。一个文档可以引入多个命名空间。
- targetNamespace:定义命名空间,其实Xml Schema的本质就是定义一个命名空间,共其他Xml引用。这边的命名空间定义为URI为 "http://www.w3school.com.cn" ,引用的时候也必须是这个
- 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>
- xmlns:引入命名空间约束 ,只是虚的路径,需要 schemaLocation具体指定位置
- 使用xmlns:xsi指定为来自的命名空间为 W3C,固定用法
- schemaLocation:辅助xmlns引入“实”的命名空间,指定具体的命名空间所指向的文件,需要具体路径。2部分组成:定义好的命名空间路径 + 具体schema文件的路径
简易元素指那些仅包含文本的元素。它不会包含任何其他的元素或属性;此处“仅包含文本”里的“文本”有很多类型;它可以是 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 处理器将移除所有空白字符(换行、回车、空格以及制表符)
复合元素指包含其他元素及/或属性的 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 指示器用于定义元素的顺序
- 指示器规定子元素可以按照任意顺序出现,且每个子元素必须只出现一次(当使用 指示器时,你可以把 设置为 0 或者 1,而只能把 指示器设置为 1)
- 指示器规定可出现某个子元素或者可出现另外一个子元素(非此即彼)
- 规定子元素必须按照特定的顺序出现
用于定义某个元素出现的频率
- 指示器可规定某个元素可出现的最大次数
- 指示器可规定某个元素能够出现的最小次数
- 如需使某个元素的出现次数不受限制,可以使用 maxOccurs="unbounded"
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",是合法的
元素也是一样的用法
字符串的数据类型表如下所示:
请注意,所有以下的数据类型均衍生于字符串数据类型(除了字符串数据类型本身)!
名称 | 描述 |
---|---|
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