2.5. 定义复杂数据类型

摘要

XML Schema 提供了一种灵活、强大的机制,用于从其简单数据类型构建复杂数据结构。您可以通过创建一系列元素和属性来创建数据结构。您还可以扩展定义的类型,以创建更复杂的类型。

除了构建复杂数据结构外,您还可以描述专用类型,如枚举类型、具有特定值的数据类型或需要遵循特定模式的数据类型,通过扩展或限制原语类型。

2.5.1. 定义数据结构

概述

在 XML Schema 中,是数据字段集合的数据集使用 复杂的Type 元素进行定义。指定复杂类型需要三段信息:

  1. 定义的类型的名称在 complexType 元素的 name 属性中指定。
  2. complexType 的第一个子元素描述结构字段在线上时的行为。请参阅 “复杂类型 varieties”一节
  3. 定义的结构的每个字段都在 复杂Type 元素中的元素中定义。请参阅 “定义结构的部分”一节

例如: 例 2.3 “简单结构” 中显示的结构在 XML Schema 中定义为带有两个元素的复杂类型。

例 2.3. 简单结构

struct personalInfo
{
  string name;
  int age;
};

例 2.4 “复杂类型” 显示 例 2.3 “简单结构” 中显示的结构的一个可能 XML Schema 映射,例 2.4 “复杂类型” 中定义的结构会生成包括两个元素: nameage 的消息。

.

例 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 “复杂的类型描述符元素” 显示用来定义复杂类型行为的元素。

表 2.1. 复杂的类型描述符元素

element复杂的类型行为

sequence

所有复杂的类型字段都可以存在,它们必须按照类型定义中指定的顺序。

all

所有复杂的类型字段都可以存在,但可以按照任何顺序排列。

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>

定义结构的部分

您可以使用 元素 定义组成结构的数据字段。每个 complexType 元素都应该包含至少一个 元素complexType 元素 中的每个元素都表示定义的数据结构中的一个字段。

要完全描述数据结构中的字段,元素 元素有两个必要属性:

  • name 属性指定 data 字段的名称,它必须在定义的复杂类型内唯一。
  • type 属性指定字段中存储的数据类型。类型可以是 XML Schema 的简单类型之一,也可以是合同中定义的任何指定复杂类型。

除了名称和类型 外,元素 还有两个常用的可选属性: minOcurrsmaxOccurs 这些属性根据字段在结构中发生的次数绑定。默认情况下,每个字段仅在复杂类型中仅发生一次。通过使用这些属性,您可以更改字段必须或可在结构中出现的次数。例如,您可以定义一个字段( 之前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 元素定义中定义 属性 元素。属性 元素只能在 所有sequencechoice 元素后面出现。为每个复杂类型的属性指定一个 属性 元素。任何 属性 元素都必须是 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 属性。属性 元素具有这些属性:

  • Name - 指定 标识属性的字符串的必需属性。
  • type - 指定字段中存储的数据类型。类型可以是 XML Schema 简单类型之一。
  • 使用 - 指定一个可选属性,用于指定是否需要复杂的类型来具有此属性。有效值 是必需的可选。默认值是 属性是可选的。

属性 元素中,您可以指定可选 默认 属性,这可让您为属性指定默认值。

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 结构。

由扩展定义的类型有四个部分:

  1. 类型的名称由 complexType 元素的 name 属性定义。
  2. complexContent 元素指定新类型将拥有多个元素。

    注意

    如果您只向复杂类型添加新属性,您可以使用 simpleContent 元素。

  3. 新类型派生的类型(称为 基本 类型)是在 extension 元素的 base 属性中指定
  4. 新的类型的元素和属性在 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 元素来定义简单类型的新类型。

按限制划分的定义需要三个因素:

  1. 新类型的名称由 simpleType 元素的 name 属性指定。
  2. 新类型派生自的简单类型(称为 基本类型 )是在 limit 元素中指定。请参阅 “指定基本类型”一节
  3. 名为 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>