XML Schema Part 2 Week 4
提要
匿名与命名类型,来自于:简单和复杂类型
范围,设计与编写XML Schema
匿名与命名类型
幽默的说是无名和有名类型。用户定义的数据类型可以是有名和无名的,有名可以允许我们重用以定义的类型。匿名类型在定义的时候不用名字。
<xs:element name=“title”>
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="language" type="xs:string" use="required"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
命名类型在定义的时候要带个名字。
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:complexType name="person">
<xs:sequence>
<xs:element name="firstname" type="xs:string"/>
<xs:element name="lastname" type="xs:string"/>
</xs:sequence>
</xs:complexType>
<xs:element name="book">
<xs:complexType>
<xs:sequence>
<xs:element name="author" type="person"/>
<xs:element name="editor" type="person"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
写出来xml就是
<?xml version="1.0" encoding="UTF-8"?>
<book xmlns:xsi="http://www.w3.org/2001/XMLSchema-instanc xsi:noNamespaceSchemaLocation="namedType.xsd">
<author>
<firstname>John</firstname>
<lastname>Howard</lastname>
</author>
<editor>
<firstname>George</firstname>
<lastname>Bush</lastname>
</editor>
</book> (这里澳大利亚人跟它们的总统和布什开了个玩笑,呵呵)
衍生数据类型
可以通过扩展或者约束方法来创建。扩展有些相似于OO建模中的泛化,约束有些像OO建模中的继承。
简单类型衍生
由约束衍生,使用xs:restriction。可以由列表(list)衍生,也可以是Union(联合)衍生。但是不可能是用由扩展方式衍生简单类型的。约束可以用来:指定范围,指定长度,指定样式等等。
指定范围的约束:
<xs:element name="myAge">
<xs:simpleType>
<xs:restriction base="xs:decimal">
<xs:totalDigits value="2"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name=“height”>
<xs:restriction base=“xs:integer”>
<xs:minInclusive value=“150”/>
<xs:maxExclusive value=“251”/>
</xs:restriction>
</xs:simpleType>
指定枚举
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="S"/>
<xs:enumeration value="M"/>
<xs:enumeration value="L"/>
<xs:enumeration value="XL"/>
</xs:restriction>
</xs:simpleType>
指定样式
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:pattern value="[A-Z]{3}[0-9]{3}"/>
</xs:restriction>
</xs:simpleType>
正则表达式,简介
一种样式定义语言用来去进行样式匹配。
正则表达式中的字符
边界
{n}精确的指明它前面的项目要匹配要重复的次数
{n,}指定它前面的项目至少要匹配多少次
{n,m}只等它前面的项目匹配的最小n次,最大m次
?,+,*同dos通配符
括号
[]匹配任何一个内部有的字符
[下界-上界]匹配上界和下界内任意一个字符
[^]匹配任何一个括号内没有的字符
衍生列表
衍生自列表是一种机制,它可以生成一个从原子数据类型衍生出来的列表。列表中所有的项目都要有相同的数据类型。例如:<integerList> 5 6 7 8 9 110<integerList>.
注意:到目前为止,解析器一般不支持列表衍生类型,所以如果你用XPath 1.0的话,是不能定位到一个列表成员的。
实例:
<xs:element name="size">
<xs:simpleType>
<xs:list itemType="xs:integer"/>
</xs:simpleType>
</xs:element>
由联合(Union)衍生
从union衍生过来的类型允许通过合并多个内建用户衍生类型来定义一个新的数据类型。
例如,用户类型1是衬衫的大小号码
<xs:simpleType name="sizeLetter">
<xs:restriction base="xs:string">
<xs:enumeration value="S"/>
<xs:enumeration value="M"/>
<xs:enumeration value="L"/>
<xs:enumeration value="XL"/>
</xs:restriction>
</xs:simpleType>
用户类型2是衬衫的数字尺寸
<xs:simpleType name="sizeNumber">
<xs:restriction base="xs:integer">
<xs:enumeration value="26"/>
<xs:enumeration value="30"/>
<xs:enumeration value="34"/>
<xs:enumeration value="38"/>
</xs:restriction>
</xs:simpleType>
通过合并诞生的新类型就是:
<xs:element name="myJeans">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="size">
<xs:simpleType>
<xs:union memberTypes="sizeNumber sizeLetter"/>
</xs:simpleType>
</xs:attribute>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
衍生自复杂类型
扩展:子元素(不能用简单内容的复杂类型)、添加属性
约束:移除素或者属性
增加元素
举例来说,对于一个Person的复杂类型,有如下定义
<xs:complexType name=“person”>
<xs:sequence>
<xs:element name="firstname" type="xs:string"/>
<xs:element name="lastname" type="xs:string"/>
</xs:sequence>
</xs:complexType>
现在要有个author元素,要使用person类,并且要对它增加一些元素和属性
<xs:element name="author“>
<xs:complexType>
<xs:complexContent>
<xs:extension base="person">
<xs:sequence>
<xs:element name="nationality“ type="xs:string"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
</xs:element>
添加属性
与前面元素定义的时候直接增加属性不同,我们这里是对某种现成的类型性进行扩展(继承)来增加属性。参见如下两端增加属性的代码
<!–-吧一个属性添加到简单类型来构成一个复杂类型-->
<xs:element name="title">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="language" type="xs:string" use="required"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
<!–- 把属性添加到复杂类型中 -->
<xs:element name="author">
<xs:complexType>
<xs:complexContent>
<xs:extension base="person">
<xs:attribute name="sex"/>
</xs:extension>
</xs:complexContent>
</xs:complexType>
</xs:element>
删除子元素
<xs:complexType name=“person”>
<xs:sequence>
<xs:element name="firstname" type="xs:string"/>
<xs:element name="lastname" type="xs:string"/>
</xs:sequence>
<xs:attribute name=“ID" type="xs:ID" use="prohibited"/>
</xs:complexType>
删除属性
<xs:element name="book">
<xs:complexType>
<xs:sequence>
<xs:element name="author">
<xs:complexType>
<xs:complexContent>
<xs:restriction base="person">
<xs:sequence>
<xs:element name="firstname" type="xs:string"/>
<xs:element name="lastname" type="xs:string"/>
</xs:sequence>
<xs:attribute name=“ID" type="xs:ID" use="prohibited"/>
</xs:restriction>
</xs:complexContent>
</xs:complexType>
</xs:element>
<xs:element name="editor" type="person"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
声明和定义的范围
元素或者属性可以声明为局部或者全局的。如果它们被当成一个schema的子元素被声明了,那就是全聚德。如果是其他元素的子元素就是局部的。这些都比较好理解,就不给示例了。
实际应用中局部和全局声明的种类
Russian Doll:仅使用局部声明,因为是元素套着元素,所以看起来就跟俄罗斯套娃一样一层套一层,因而得名。
Salami:仅仅使用全局声明。因为都是全局元素,所以不存在元素嵌套。因为其排列方式跟意大利腊肠挂起来一样一个排一个,彼此没有关联,所以得名。
Venetian Blind:对所有的复杂类型使用命名类型。(即所有的复杂类型都要有名字)
Garden Of Eden:salami和venetian blind的混合。
示例:
Russian Doll
<xs:element name="book">
<xs:complexType>
<xs:sequence>
<xs:element name="title" type="xs:string"/>
<xs:element name="author">
<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:sequence>
</xs:complexType>
</xs:element>
Salami Design
<xs:element name="title" type="xs:string"/>
<xs:element name="firstname" type="xs:string"/>
<xs:element name="lastname" type="xs:string"/>
<xs:element name=“author">
<xs:complexType>
<xs:sequence>
<xs:element ref="firstname"/>
<xs:element ref="lastname"/>
</xs:sequence>
</xs:complexType>
</xs:element>
威尼斯设计
<xs:complexType name="person">
<xs:sequence>
<xs:element name="firstname" type="xs:string"/>
<xs:element name="lastname" type="xs:string"/>
</xs:sequence>
</xs:complexType>
<xs:element name="book">
<xs:complexType>
<xs:sequence>
<xs:element name="title" type="xs:string"/>
<xs:element name="author" type="person"/>
</xs:sequence>
</xs:complexType>
</xs:element>
伊甸园模式
<xs:complexType name=“person”>
<xs:sequence>
<xs:element ref="firstname"/>
<xs:element ref="lastname"/>
</xs:sequence>
</xs:complexType>
<xs:element name="title" type="xs:string"/>
<xs:element name="firstname" type="xs:string"/>
<xs:element name="lastname" type="xs:string"/>
<xs:element name=“author“ type=“person”/>
<xs:element name="book">
<xs:complexType>
<xs:sequence>
<xs:element ref="title"/>
<xs:element ref=“author“/>
</xs:sequence>
</xs:complexType>
</xs:element>
至于具体用到哪个,参见Global versus Local
命名类型和全局声明模式
注意比较两种方式在定义schema和书写xml上的不同。
• 命名类型
<xs:complexType name="person">
<xs:sequence>
<xs:element name="firstname“ ype="xs:string"/>
<xs:element name="lastname“ type="xs:string"/>
</xs:sequence>
</xs:complexType>
<xs:element name=“author” type=“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=“author”>
<xs:complexType>
<xs:sequence>
<xs:element ref=“person”/>
</xs:sequence>
</xs:complexType>
<xs:element>
•命名类型XML
<?xml version="1.0"?>
<author xsi:noNamespaceSchemaLocation="namedTypeAuthor.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<firstname>Maria</firstname>
<lastname>Indrawan</lastname>
</author>
•全局声明类型的XML
<?xml version="1.0"?>
<author xsi:noNamespaceSchemaLocation="authorGlobal.xml“ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<person>
<firstname>Maria</firstname>
<lastname>Indrawan</lastname>
</person>
</author>