2.5. 定义复杂数据类型
摘要
XML Schema 提供了一种灵活、强大的机制,用于从其简单数据类型构建复杂数据结构。您可以通过创建一系列元素和属性来创建数据结构。您还可以扩展定义的类型,以创建更复杂的类型。
除了构建复杂数据结构外,您还可以描述专用类型,如枚举类型、具有特定值的数据类型或需要遵循特定模式的数据类型,通过扩展或限制原语类型。
2.5.1. 定义数据结构
概述
在 XML Schema 中,是数据字段集合的数据集使用 复杂的Type
元素进行定义。指定复杂类型需要三段信息:
-
定义的类型的名称在
complexType
元素的name
属性中指定。 -
complexType
的第一个子元素描述结构字段在线上时的行为。请参阅 “复杂类型 varieties”一节。 -
定义的结构的每个字段都在
复杂Type
元素中的元素中定义。请参阅 “定义结构的部分”一节。
例如: 例 2.3 “简单结构” 中显示的结构在 XML Schema 中定义为带有两个元素的复杂类型。
例 2.3. 简单结构
struct personalInfo { string name; int age; };
例 2.4 “复杂类型” 显示 例 2.3 “简单结构” 中显示的结构的一个可能 XML Schema 映射,例 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 Schema 有三种方法:描述复杂类型的字段在以 XML 文档表示并传递线时如何组织。complexType
元素的第一个子元素决定了使用哪一种复杂类型。表 2.1 “复杂的类型描述符元素” 显示用来定义复杂类型行为的元素。
element | 复杂的类型行为 |
---|---|
所有复杂的类型字段都可以存在,它们必须按照类型定义中指定的顺序。 | |
所有复杂的类型字段都可以存在,但可以按照任何顺序排列。 | |
结构中只有一个元素可以放在消息中。 |
如果结构是使用 选择
元素定义的,如 例 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
。
这些属性根据字段在结构中发生的次数绑定。默认情况下,每个字段仅在复杂类型中仅发生一次。通过使用这些属性,您可以更改字段必须或可在结构中出现的次数。例如,您可以定义一个字段(
之前Jobs
),它必须至少发生三次,且不超过七次,如 例 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
设置为零(如 例 2.7 “带有 minOccurs 设置为 0 的简单复杂类型” 所示),使用 minOccurs
使 age
字段是可选的。在这种情况下,年龄
可以被省略,数据仍将有效。
例 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
元素定义中定义 属性
元素。属性
元素只能在 所有
、sequence
或 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>
在前面的代码中,属性
元素指定 personalInfo
复杂类型具有 age
属性。属性
元素具有这些属性:
在 属性
元素中,您可以指定可选 默认
属性,这可让您为属性指定默认值。
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 数组派生的语法” 中。确保 定义
元素声明 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
和 dissions 的数量,带有 []
意味着一个维度。
例 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
属性必须始终设置为 未绑定
。
2.5.3. 按扩展定义类型
与大多数主要编码语言一样,XML Schema 允许您创建数据类型,从其他数据类型继承其部分元素。这称为扩展来定义类型。例如,您可以创建一个名为 alienInfo
的新类型,通过添加名为 planet
的新元素来扩展 例 2.4 “复杂类型” 中定义的 personalInfo
结构。
由扩展定义的类型有四个部分:
-
类型的名称由
complexType
元素的name
属性定义。 complexContent
元素指定新类型将拥有多个元素。注意如果您只向复杂类型添加新属性,您可以使用
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 Schema 允许您通过限制 XML Schema 简单类型可能的值来创建新类型。例如,您可以定义一个简单的类型 SSN
,字符串为正好 9 个字符。通过限制使用 simpleType
元素来定义简单类型的新类型。
按限制划分的定义需要三个因素:
-
新类型的名称由
simpleType
元素的name
属性指定。 -
新类型派生自的简单类型(称为 基本类型 )是在 limit 元素中指定。
请参阅 “指定基本类型”一节。
-
名为 facets 的规则,定义基本类型的限制被定义为
限制
元素的子项。请参阅 “定义限制”一节。
指定基本类型
基础类型是被限制在定义新类型中的类型。它使用 限制
元素来指定。limit 元素是 simpleType
元素的唯一子项,它有一个属性 base
,用于指定基本类型。基础类型可以是任何 XML Schema 简单的类型。
例如,若要通过限制 xsd:int
的值来定义一个新类型,您可以使用类似 例 2.14 “使用 int 作为基本类型” 所示的定义。
例 2.14. 使用 int 作为基本类型
<simpleType name="restrictedInt"> <restriction base="xsd:int"> ... </restriction> </simpleType>
定义限制
定义对基本类型的限制的规则被称为 facets。facets 是带有一个属性( 值
)的元素,用于定义 facet 的强制实施方式。可用因素及其 有效值
设置取决于基本类型。例如,xsd:string
支持六个问题,包括:
-
length
-
minLength
-
maxLength
-
pattern
-
whitespace
-
enumeration
每个 facet 元素都是 限制
元素的子项。
示例
例 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 Schema 中枚举的类型是一个根据限制定义的特殊情形。它们通过使用枚举的 枚举来说明
,它受所有 XML Schema 原语类型的支持。与大多数现代编程语言中枚举类型一样,此类型的变量只能具有一个指定的值。
在 XML Schema 中定义枚举
例 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 是任意数字一或大于值,指定枚举每个具体案例的值。枚举的类型可以具有任意数量的 case 值,但它源自一个简单类型,因此一次只有其中一个问题单值才有效。
示例
例如,如果一个含有 < widgetSize
>big</widgetSize>big</widgetSize>,则由 enumeration widgetSize> 定义元素的 XML 文档在 例 2.17 “widgetSize enumeration” 中包含 <widgetSize> 时才有效。
例 2.17. widgetSize enumeration
<simpleType name="widgetSize"> <restriction base="xsd:string"> <enumeration value="big"/> <enumeration value="large"/> <enumeration value="mungo"/> </restriction> </simpleType>