2.5. 定义复杂数据类型
摘要
XML 架构提供了灵活的强大机制,用于从其简单数据类型构建复杂数据结构。您可以通过创建由元素和属性组成的序列来创建数据结构。您还可以扩展您定义的类型,以创建更复杂的类型。
除了构建复杂数据结构外,您还可以描述专用类型,如枚举类型、具有特定范围的值的数据类型,或者通过扩展或限制原语类型需要遵守特定模式的数据类型。
2.5.1. 定义数据结构
概述
在 XML 架构中,作为数据字段集合的数据单元是使用 complexType
元素来定义的。指定复杂类型需要三部分信息:
-
定义的类型的名称在
complexType
元素的name
属性中指定。 -
complexType
的第一个子元素描述了当 structure 字段在线路上时的行为。请参阅 “复杂的类型 varieties”一节。 -
定义结构的每个字段都在作为
complexType
元素的 Getndchildren 的元素中定义。请参阅 “定义结构的部分”一节。
例如,在 XML 架构中作为带有两个元素的复杂类型来定义 例 2.3 “简单结构” 中的结构。
例 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>
复杂的类型 varieties
XML 架构有三种方法来描述复杂类型的字段在以 XML 文档表示并用线路传递时的方式。complexType
元素的第一个子元素决定使用哪些复杂类型。表 2.1 “复杂的类型描述符元素” 显示用于定义复杂类型行为的元素。
元素 | 复杂的类型行为 |
---|---|
所有复杂类型的字段都可以存在,且它们必须按类型定义中指定的顺序。 | |
所有复杂的类型字段都可以存在,但可以按任何顺序排列。 | |
只有结构中的其中一个元素可以放在消息中。 |
如果使用 选择
元素定义结构,如 例 2.5 “简单复杂的选择类型” 所示,它将生成一个包含 name
元素或 age
元素的消息。
例 2.5. 简单复杂的选择类型
<complexType name="personalInfo"> <choice> <element name="name" type="xsd:string"/> <element name="age" type="xsd:int"/> </choice> </complexType>
定义结构的部分
您可以使用 元素元素
定义组成结构的数据字段。每个 complexType
元素都应该至少包含一个 元素
。complexType
元素
中的每个元素代表定义的数据结构中的一个字段。
要完全描述数据结构中的字段,元素
元素有两个所需的属性:
除了名称和类型外,元素元素
还有两个常用的可选属性: minOcurrs
和 maxOccurs
。
这些属性根据字段在结构中发生的次数进行绑定。默认情况下,每个字段仅在复杂类型中执行一次。使用这些属性,您可以更改字段必须或可以在结构中显示的次数。例如,您可以定义一个字段
previousJobs
,它必须至少发生三次,且不超过七次,如 例 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>
您还可以通过将 minOccurs
设置为 0,使用 minOccurs
来指定 age
字段是可选的,如 例 2.7 “简单的复杂类型,将 minOccurs 设为零” 所示。在这种情况下,可以省略这些 年龄
,数据仍将有效。
例 2.7. 简单的复杂类型,将 minOccurs 设为零
<complexType name="personalInfo"> <choice> <element name="name" type="xsd:string"/> <element name="age" type="xsd:int" minOccurs="0"/> </choice> </complexType>
定义属性
在 XML 文档中,属性包含在元素的标签中。例如,在下面的代码中的 complexType
元素中,name
是属性。要为复杂类型指定属性,您可以在 complexType
元素定义中定义 属性
元素。属性
元素只能在 所有
、序列
或选择元素 后显示
。为每个复杂类型的属性指定一个 属性
元素。任何 属性
元素都必须是 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 阵列通过除 SOAP-ENC:Array
基本类型使用 wsdl:arrayType
元素来定义。这个语法显示在 例 2.10 “使用 wsdl:arrayType 派生的 SOAP 阵列语法” 中。确保 definition 元素声明 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 指定阵列中的维度数。要指定单一维度数组使用 []
; 指定双维数组,使用 [][]
或 [,]
。
例如: 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 Array,如 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
属性必须始终设为 unbound
。
2.5.3. 按扩展定义类型
与大多数主要的编码语言一样,XML Schema 也允许您创建数据类型来继承其某些元素的数据类型。这称为按照扩展来定义类型。例如,您可以创建一个名为 alienInfo
的新类型,它通过添加一个名为 planet
的新元素来扩展 例 2.4 “复杂类型” 中定义的 个人Info
结构。
由 扩展定义的类型有四个部分:
-
类型的名称由
complexType
元素的name
属性定义。 复杂的Content
元素指定新类型将具有多个元素。注意如果您只向复杂类型添加新属性,您可以使用
simpleContent
元素。-
从派生新类型的类型(称为 基础 类型)在
extension
元素的base
属性中指定。 -
新类型的元素和属性在
extension
元素中定义,它们与用于常规复杂的类型相同。
例如: alienInfo
定义,如 例 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 架构允许您通过限制 XML 架构简单类型的可能值来创建新类型。例如,您可以定义一个简单类型 SSN
,它是仅包含 9 个字符的字符串。通过限制简单类型来定义的新类型,可使用 simpleType
元素来定义。
按限制划分类型的定义需要三个操作:
-
新类型的名称通过
simpleType
元素的name
属性指定。 -
从中派生新类型的简单类型(称为 基础类型 )在 limits 元素中指定。
请参阅 “指定基础类型”一节。
-
规则(称为 facets )定义基础类型所施加的限制是作为
限制
元素的子项的子项。请参阅 “定义限制”一节。
指定基础类型
基础类型是受限制来定义新类型的类型。它通过 limit 元素 来指定
。限制
元素是 simpleType
元素的唯一子项,并且具有一个指定 基础
类型的属性(base)。基本类型可以是任何 XML 架构简单类型。
例如,通过限制 xsd:int
的值来定义新类型,您可以使用类似 例 2.14 “使用 int 作为基础类型” 中显示的定义。
例 2.14. 使用 int 作为基础类型
<simpleType name="restrictedInt"> <restriction base="xsd:int"> ... </restriction> </simpleType>
定义限制
定义对基本类型实施的限制的规则称为 facets。facets 是带有一条属性( value
)的元素,它定义了如何强制实施 facet。可用的难题及其 有效值
设置取决于基本类型。例如,xsd:string
支持六方面面,其中包括:
-
length
-
minLength
-
maxLength
-
pattern
-
whitespace
-
枚举
每个 facet 元素都是 限制
元素的子元素。
示例
例 2.15 “SSN 简单类型描述” 显示了一个简单类型 SSN
的示例,它代表了一个社交安全号。生成的 type 是 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 架构中定义枚举
定义枚举的语法显示在 例 2.16 “枚举的语法” 中。
例 2.16. 枚举的语法
<simpleType name="EnumName"> <restriction base="EnumType"> <enumeration value="Case1Value"/> <enumeration value="Case2Value"/> ... <enumeration value="CaseNValue"/> </restriction> </simpleType>
EnumName 指定枚举类型的名称。EnumType 指定问题单值的类型。CaseNValue,其中 N 是任意一个或更大值,它指定枚举的每个具体案例的值。枚举的类型可以包含任意数量的问题单值,但由于从简单类型派生出,因此一次只有一个问题单值有效。
示例
例如,如果一个带有由 enumeration widgetSize 定义的元素的 XML 文档,如果它包括了 < widgetSize
>big</widgetSize>,则它无效,但如果包含 <widgetSize>big,mungo</widgetSize>。例 2.17 “widgetSize enumeration”
例 2.17. widgetSize enumeration
<simpleType name="widgetSize"> <restriction base="xsd:string"> <enumeration value="big"/> <enumeration value="large"/> <enumeration value="mungo"/> </restriction> </simpleType>