2.5. 定义复杂数据类型
摘要
XML Schema 提供灵活、强大的机制,用于从其简单数据类型构建复杂数据结构。您可以通过创建一系列元素和属性来创建数据结构。您还可以扩展您定义的类型,以创建更复杂的类型。
除了构建复杂数据结构外,您还可以描述专用类型,如枚举的类型、具有特定值的数据类型,或者通过扩展或限制原语类型来遵循特定模式的数据类型。
2.5.1. 定义数据结构
概述
在 XML Schema 中,作为数据字段集合的数据单元使用 complexType 元素定义。指定复杂类型需要三段信息:
-
定义类型的 name 属性在
complexType元素的name属性中指定。 -
complexType的第一个子元素描述了在线上放置结构字段的行为。请参阅 “复杂类型差异”一节。 -
定义结构的每个字段都在
element元素中定义,它们是complexType元素的 grandchildren。请参阅 “定义结构的部分”一节。
例如: 例 2.3 “简单结构” 中显示的结构在 XML Schema 中定义为具有两个元素的复杂类型。
例 2.3. 简单结构
struct personalInfo
{
string name;
int age;
};
例 2.4 “复杂类型” 显示 例 2.3 “简单结构” 中显示的结构的一个可能的 XML 架构映射 例 2.4 “复杂类型” 会生成含有两个元素的消息: name 和 age。
.
例 2.4. 复杂类型
<complexType name="personalInfo">
<sequence>
<element name="name" type="xsd:string" />
<element name="age" type="xsd:int" />
</sequence>
</complexType>复杂类型差异
XML Schema 有三种方法来描述复杂类型字段在以 XML 文档表示,并在有线上传递时如何组织复杂类型字段。complexType 元素的第一个子元素决定使用哪些复杂类型。表 2.1 “复杂的类型描述符元素” 显示用于定义复杂类型行为的元素。
表 2.1. 复杂的类型描述符元素
如果使用 choice 元素定义结构,如 例 2.5 “简单的复杂选择类型” 所示,它会生成一条带有 name 元素或 age 元素的消息。
例 2.5. 简单的复杂选择类型
<complexType name="personalInfo">
<choice>
<element name="name" type="xsd:string"/>
<element name="age" type="xsd:int"/>
</choice>
</complexType>定义结构的部分
您可以使用 element 元素 定义组成结构的数据字段。每个 complexType 元素应该至少包含一个 element 元素。complexType 元素中的每个元素代表定义的数据结构中的一个字段。
要完全描述数据结构中的字段,element 元素有两个所需的属性:
除了 name 和 type 外,element 元素还有两个常用的可选属性: minOcurrs 和 maxOccurs。这些属性将绑定到字段在结构中发生的次数。默认情况下,每个字段仅在复杂类型中发生一次。使用这些属性,您可以更改字段必须或可以出现在结构中的次数。例如,您可以定义一个字段 previousJobs,它必须至少发生三次,且不超过 7 次,如 例 2.6 “发生限制的简单复杂类型” 所示。
例 2.6. 发生限制的简单复杂类型
<complexType name="personalInfo">
<all>
<element name="name" type="xsd:string"/>
<element name="age" type="xsd:int"/>
<element name="previousJobs" type="xsd:string:
minOccurs="3" maxOccurs="7"/>
</all>
</complexType>
您还可以通过将 设置为 0 来使 minOccurs age 字段是可选的,如 例 2.7 “将 minOccurs 设置为 0 的简单复杂类型” 所示。在这种情况下,可以省略 年龄,数据仍会有效。
例 2.7. 将 minOccurs 设置为 0 的简单复杂类型
<complexType name="personalInfo">
<choice>
<element name="name" type="xsd:string"/>
<element name="age" type="xsd:int" minOccurs="0"/>
</choice>
</complexType>定义属性
在 XML 文档中,属性包含在元素的标签中。例如,在以下代码中的 complexType 元素中,name 是属性。要为复杂类型指定属性,您可以在 complexType 元素定义中定义 attribute 元素。attribute 元素只能在 所有、序列 或 choice 元素后显示。为每个复杂类型的属性指定一个 属性 元素。任何 属性 元素都必须是 complexType 元素的直接子项。
例 2.8. 具有属性的复杂类型
<complexType name="personalInfo">
<all>
<element name="name" type="xsd:string"/>
<element name="previousJobs" type="xsd:string"
minOccurs="3" maxOccurs="7"/>
</all>
<attribute name="age" type="xsd:int" use="required" />
</complexType>
在前面的代码中,attribute 元素指定 personalInfo 复杂类型具有 age 属性。attribute 元素具有这些属性:
在 attribute 元素中,您可以指定可选的 default 属性,它可让您为属性指定默认值。
2.5.2. 定义数组
概述
Apache CXF 支持两种方法在合同中定义数组。第一种定义具有单个元素的复杂类型,其 maxOccurs 属性的值大于一。第二个方法是使用 SOAP 阵列。SOAP 阵列提供添加的功能,如轻松定义多维阵列和传输稀疏填充阵列等功能。
复杂的类型数组
复杂的类型数组是序列复杂类型的一种特殊情况。只需使用单个元素定义复杂类型,并为 maxOccurs 属性指定一个值。例如,要定义一组二个浮点数,您可以使用与 例 2.9 “复杂的类型数组” 中显示的复杂类型。
例 2.9. 复杂的类型数组
<complexType name="personalInfo"> <element name="averages" type="xsd:float" maxOccurs="20"/> </complexType>
您还可以为 minOccurs 属性指定值。
SOAP 数组
SOAP 数组通过利用 wsdl:arrayType 元素从 SOAP-ENC:Array 基本类型中定义。的语法显示在 例 2.10 “使用 wsdl:arrayType 派生的 SOAP 数组的语法” 中。确保 definitions 元素声明 xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"。
例 2.10. 使用 wsdl:arrayType 派生的 SOAP 数组的语法
<complexType name="TypeName"> <complexContent> <restriction base="SOAP-ENC:Array"> <attribute ref="SOAP-ENC:arrayType" wsdl:arrayType="ElementType<ArrayBounds>"/> </restriction> </complexContent> </complexType>
使用这个语法,TypeName 指定新定义的数组类型的名称。elementType 指定阵列中元素的类型。ArrayBounds 指定阵列中的维度数。要指定单个维度数组使用 []; 指定双维数组,请使用 [][] 或 [,]。
例如,SOA SOAP Array, SOAPStrings 在 例 2.11 “SOAP 数组的定义” 中显示,定义一个字符串的一个维度数组。wsdl:arrayType 属性指定数组元素的类型 xsd:string,以及尺寸的数量,[] 代表一个维度。
例 2.11. SOAP 数组的定义
<complexType name="SOAPStrings">
<complexContent>
<restriction base="SOAP-ENC:Array">
<attribute ref="SOAP-ENC:arrayType"
wsdl:arrayType="xsd:string[]"/>
</restriction>
</complexContent>
</complexType>您还可以使用一个简单元素来描述 SOAP 数组,如 SOAP 1.1 规范中所述。的语法显示在 例 2.12 “使用元素派生的 SOAP 数组的语法” 中。
例 2.12. 使用元素派生的 SOAP 数组的语法
<complexType name="TypeName"> <complexContent> <restriction base="SOAP-ENC:Array"> <sequence> <element name="ElementName" type="ElementType" maxOccurs="unbounded"/> </sequence> </restriction> </complexContent> </complexType>
在使用此语法时,元素的 maxOccurs 属性必须始终设置为 未绑定。
2.5.3. 通过扩展定义类型
与大多数主要编码语言一样,XML 架构允许您创建从其他数据类型继承其部分元素的数据类型。这称为按扩展定义类型。例如,您可以创建一个名为 alienInfo 的新类型,它通过添加名为 planet 的新元素来扩展 例 2.4 “复杂类型” 中定义的 personalInfo 结构。
由扩展定义的类型有四个部分:
-
类型的名称由
complexType元素的name属性定义。 complexContent元素指定新类型将有多个元素。注意如果您只向复杂类型添加新属性,您可以使用
simpleContent元素。-
新类型派生到的类型(称为 基本 类型)在
extension元素的基本属性中指定。 -
新类型的元素和属性在
extension元素中定义,这与常规复杂类型相同。
例如,ali enInfo 定义,如 例 2.13 “由扩展定义的类型” 所示。
例 2.13. 由扩展定义的类型
<complexType name="alienInfo">
<complexContent>
<extension base="xsd1:personalInfo">
<sequence>
<element name="planet" type="xsd:string"/>
</sequence>
</extension>
</complexContent>
</complexType>2.5.4. 根据限制定义类型
概述
XML Schema 允许您通过限制 XML 架构简单类型的可能值来创建新类型。例如,您可以定义一个简单的类型 SSN,它是一个正好 9 个字符的字符串。通过限制简单类型定义的新类型是使用 simpleType 元素定义的。
根据限制划分类型的定义需要三个内容:
-
新类型的名称由
simpleType元素的name属性指定。 -
新类型派生到的简单类型(称为 基本类型 )在 limitations 元素中指定。
请参阅 “指定基本类型”一节。 -
规则称为 facets,定义对基础类型实施的限制将定义为 limit 元素的子项。
请参阅 “定义限制”一节。
指定基本类型
基本类型是正在限制定义新类型的类型。它使用一个 limit 元素 来指定。限制 元素是 simpleType 元素的唯一子级,它具有一个属性 base,用于指定基本类型。基本类型可以是任何 XML 架构简单类型。
例如,通过限制 xsd:int 的值来定义一个新类型,您可以使用类似 例 2.14 “使用 int 作为基本类型” 所示的定义。
例 2.14. 使用 int 作为基本类型
<simpleType name="restrictedInt">
<restriction base="xsd:int">
...
</restriction>
</simpleType>定义限制
定义对基本类型的限制的规则称为 facets。facet 是指一个属性( 值为 )的元素,用于定义如何强制实施 facet。可用的 facet 及其 有效值 设置取决于基本类型。例如,xsd:string 支持六个 facets,包括:
-
length -
minLength -
maxLength -
pattern -
whitespace -
Enumeration
每个 facet 元素都是 Limit 元素 的子级。
示例
例 2.15 “SSN 简单类型描述” 显示了一个简单的类型 SSN 的示例,它代表社交安全号码。生成的类型是一个字符串,格式为 xxx-xx-xxxx。<SSN>032-43-9876<SSN> 是此类型的元素的有效值,但 <SSN>032439876</SSN> 不是。
例 2.15. SSN 简单类型描述
<simpleType name="SSN">
<restriction base="xsd:string">
<pattern value="\d{3}-\d{2}-\d{4}"/>
</restriction>
</simpleType>2.5.5. 定义枚举类型
概述
XML 架构中的枚举类型是按限制划分的特殊定义情况。它们通过使用所有 XML 架构原语类型支持的 枚举 情况进行描述。与大多数现代编程语言中枚举的类型一样,此类型的变量只能具有指定的值之一。
在 XML Schema 中定义枚举
例 2.16 “Enumeration 的语法” 中显示定义枚举的语法。
例 2.16. Enumeration 的语法
<simpleType name="EnumName"> <restriction base="EnumType"> <enumeration value="Case1Value"/> <enumeration value="Case2Value"/> ... <enumeration value="CaseNValue"/> </restriction> </simpleType>
EnumName 指定枚举类型的名称。EnumType 指定问题单值的类型。CaseNValue,其中 N 是一个或多个,指定枚举的每个特定情况的值。Enumerated 类型可以具有任意数量的问题单值,但它是从一个简单的类型派生的,因此一次只有一个 case 值有效。
示例
例如,一个由 enumeration widgetSize 定义的一个元素的 XML 文档(在 例 2.17 “widgetSize enumeration” 中显示),如果它包含 < widgetSize >big</widgetSize>,则它将无效,但如果它包含 <widgetSize>big,mungo</widgetSize>,它将无效。
例 2.17. widgetSize enumeration
<simpleType name="widgetSize">
<restriction base="xsd:string">
<enumeration value="big"/>
<enumeration value="large"/>
<enumeration value="mungo"/>
</restriction>
</simpleType>