36.2. 使用 XML 架构任何类型

概述

XML 架构类型 xsd:anyType 是所有 XML 架构类型的 root 类型。所有原语都是这种类型的衍生产品,因为所有用户定义的所有复杂类型。因此,作为 xsd:anyType 定义的元素可以包含任何 XML 架构原语形式的数据,以及架构文档中定义的任何复杂类型。

在 Java 中,最匹配的类型是 Object 类。它是下级其他所有 Java 类的子类。

在 XML 架构中使用

您可以使用 xsd:anyType 类型作为其它 XML 架构复杂类型。它可以用作元素的 type 元素 的值。它还可用作定义其他类型的基本类型。

例 36.5 “带有通配符元素的复杂类型” 显示包含类型为 xsd:anyType 的复杂类型的示例。

例 36.5. 带有通配符元素的复杂类型

<complexType name="wildStar">
  <sequence>
    <element name="name" type="xsd:string" />
    <element name="ship" type="xsd:anyType" />
  </sequence>
</complexType>

映射到 Java

类型为 xsd:anyType 的元素映射到对象 对象例 36.6 “Java 代表通配符元素” 显示 例 36.5 “带有通配符元素的复杂类型” 到 Java 类的映射。

例 36.6. Java 代表通配符元素

public class WildStar {

    @XmlElement(required = true)
    protected String name;
    @XmlElement(required = true) protected Object ship;

    public String getName() {
        return name;
    }

    public void setName(String value) {
        this.name = value;
    }

    public Object getShip() { return ship; }

    public void setShip(Object value) { this.ship = value; }
}

此映射允许您将任何数据放在代表通配卡元素的 属性中。Apache CXF 运行时处理数据碎片化和解包化,形成可用的 Java 表示。

marshalling

当 Apache CXF marshals XML 数据进入 Java 类型时,它会尝试 将任何Type 元素放入已知的 JAXB 对象。要确定如何将 任何Type 元素放入一个 JAXB 生成的对象,运行时将检查元素的 xsi:type 属性,以确定用于在元素中构造数据的实际类型。如果 xsi:type 属性不存在,则运行时会尝试按内省来识别元素的实际数据类型。如果元素的实际数据类型决定为应用的 JAXB 上下文已知的类型之一,则该元素被放入正确类型的 JAXB 对象。

如果运行时无法确定元素的实际数据类型,或者元素的实际数据类型不是已知类型,则运行时会将内容放入 org.w3c.dom.Element 对象。然后,您将需要使用 DOM APis 与元素的内容一起工作。

应用的运行时通常知道从其合同中包含的架构生成的所有类型。其中包括合同中与 dl:types 元素中定义的类型、通过包含添加到合同的任何数据类型,以及通过导入其他架构文档添加到合同中的任何类型。您还可以使用 @XmlSeeAlso 注释使运行时了解额外类型,如 第 32.4 节 “在 Runtime Marshaller 中添加类” 所述。

unmarshalling

当 Apache CXF unmarshals Java 类型到 XML 数据时,它使用 Java 数据类型和 XML 架构结构之间的内部映射,以确定其对线的 XML 结构。如果运行时知道类,可以将类映射到 XML 架构结构,它将写入数据并插入 xsi:type 属性来识别元素包含的数据类型。如果数据存储在 org.w3c.dom.Element 对象中,运行时会写入对象代表的 XML 结构,但它不包含 xsi:type 属性。

如果运行时无法将 Java 对象映射到已知的 XML 架构结构,它会抛出一个marshaling 异常。您可以使用 @XmlSeeAlso 注释(如 第 32.4 节 “在 Runtime Marshaller 中添加类” 中所述),向运行时添加类型。