35.4. 从复杂类型分离复杂类型

概述

通过使用 XML 架构,您可以通过扩展或限制复杂 内容元素来生成新的复杂 类型。当生成 Java 类以表示派生复杂类型时,Apache CXF 扩展基础类型的类。这样,生成的 Java 代码会保留在 XML 架构中预期的继承层次结构。

模式语法

您可以使用 复杂的Content 元素以及 extension 元素或 limit 元素从其他复杂类型生成复杂类型。复杂的Content 元素指定包含的数据描述包含多个字段。extension 元素和 restrictions 元素(即 复杂Content 元素的子项)指定正在修改的基础类型以创建新类型。基础类型由 base 属性指定。

扩展复杂类型

要扩展复杂类型,请使用 扩展 元素来定义组成新类型的额外元素和属性。在复杂类型描述中允许的所有元素都可以作为新类型的定义的一部分。例如,您可以向新类型添加匿名枚举,也可以使用 choice 元素来指定仅新字段之一每次都有效。

例 35.15 “按扩展划分划分复杂类型” 显示定义两种复杂类型的 XML 架构片段,即 widgetOrderInfowidgetOrderBillInfowidgetOrderBillInfo 通过扩展 widgetOrderInfo 来包括两个新元素: orderNumberamtDue

例 35.15. 按扩展划分划分复杂类型

<complexType name="widgetOrderInfo">
  <sequence>
    <element name="amount" type="xsd:int"/>
    <element name="order_date" type="xsd:dateTime"/>
    <element name="type" type="xsd1:widgetSize"/>
    <element name="shippingAddress" type="xsd1:Address"/>
  </sequence>
  <attribute name="rush" type="xsd:boolean" use="optional" />
</complexType>
<complexType name="widgetOrderBillInfo">
  <complexContent>
    <extension base="xsd1:widgetOrderInfo">
      <sequence>
        <element name="amtDue" type="xsd:decimal"/>
        <element name="orderNumber" type="xsd:string"/>
      </sequence>
      <attribute name="paid" type="xsd:boolean"
                 default="false" />
    </extension>
  </complexContent>
</complexType>

限制复杂类型

要限制复杂类型,请使用 limits 元素来限制基础类型的元素或属性的可能值。在限制复杂类型时,您必须列出基本类型的所有元素和属性。对于每个元素,您可以在定义中添加限制属性。例如,您可以在元素中添加 maxOccurs 属性来限制它可以被发生的次数。您还可以使用 固定 属性强制一个或多个元素具有预先确定的值。

例 35.16 “根据限制定义复杂类型” 演示了通过限制另一个复杂类型来定义复杂类型的示例。受限类型 wallawallaAddress 只能用于 Walla Walla、Washington 中的地址,因为 城市 元素、state 元素和 zipCode 元素的值会被修复。

例 35.16. 根据限制定义复杂类型

<complexType name="Address">
  <sequence>
    <element name="name" type="xsd:string"/>
    <element name="street" type="xsd:short" maxOccurs="3"/>
    <element name="city" type="xsd:string"/>
    <element name="state" type="xsd:string"/>
    <element name="zipCode" type="xsd:string"/>
  </sequence>
</complexType>
<complexType name="wallawallaAddress">
  <complexContent>
    <restriction base="xsd1:Address">
      <sequence>
        <element name="name" type="xsd:string"/>
        <element name="street" type="xsd:short"
                 maxOccurs="3"/>
        <element name="city" type="xsd:string"
                 fixed="WallaWalla"/>
        <element name="state" type="xsd:string"
                 fixed="WA" />
        <element name="zipCode" type="xsd:string"
                 fixed="99362" />
      </sequence>
    </restriction>
  </complexContent>
</complexType>

映射到 Java

与所有复杂类型一样,Apache CXF 生成一个类来代表从另一个复杂类型派生的复杂类型。为派生复杂类型生成的 Java 类扩展了生成的 Java 类,以支持基础复杂类型。基本 Java 类也会修改为包含 @XmlSeeAlso 注释。base 类的 @XmlSeeAlso 注释列出了扩展基础类的所有类。

当通过扩展生成新复杂类型时,生成的类将包含所有添加元素和属性的成员变量。新成员变量将根据与所有其他元素相同的映射生成。

当根据限制派生出新复杂类型时,生成的类将没有新的成员变量。生成的类将只是一个 shell,它不提供任何附加功能。您完全是您确保强制实施 XML 架构中定义的限制。

例如,例 35.15 “按扩展划分划分复杂类型” 中的 schema 会产生两个 Java 类的生成:Flay OrderInfoWidgetBillOrderInfo。widget OrderBillInfo 扩展 widget OrderInfo,因为 widgetOrderBillInfo 是由来自 widgetOrderInfo 的扩展。例 35.17 “WidgetOrderBillInfo” 显示 widgetOrderBillInfo 生成的类。

例 35.17. WidgetOrderBillInfo

@XmlType(name = "widgetOrderBillInfo", propOrder = {
    "amtDue",
    "orderNumber"
})
public class WidgetOrderBillInfo
    extends WidgetOrderInfo
{
    @XmlElement(required = true)
    protected BigDecimal amtDue;
    @XmlElement(required = true)
    protected String orderNumber;
    @XmlAttribute
    protected Boolean paid;

    public BigDecimal getAmtDue() {
        return amtDue;
    }

    public void setAmtDue(BigDecimal value) {
        this.amtDue = value;
    }

    public String getOrderNumber() {
        return orderNumber;
    }

    public void setOrderNumber(String value) {
        this.orderNumber = value;
    }

    public boolean isPaid() {
        if (paid == null) {
            return false;
        } else {
            return paid;
        }
    }

    public void setPaid(Boolean value) {
        this.paid = value;
    }
}