第 33 章 使用 XML 元素
摘要
XML 架构元素用于定义 XML 文档中的元素实例。元素可以在 XML 架构文档的全局范围内定义,或者定义为复杂类型的成员。当它们在全局范围内定义时,Apache CXF 将它们映射到一个 JAXB 元素类,以便更轻松地操作它们。
概述
XML 文档中的一个元素实例由 XML 架构文档全局范围内的 XML Schema 元素定义,以便 Java 开发人员更轻松地处理元素,Apache CXF 将全局范围的元素映射到特殊的 JAXB 元素类或生成的 Java 类,以匹配其内容类型。
该元素是如何映射的,这取决于元素是否使用 type
属性引用的命名类型定义,或者该元素是使用 in-line 类型定义定义的。使用 in-line 类型定义定义的元素映射到 Java 类。
建议使用命名类型来定义元素,因为 in-line 类型无法被架构中的其他元素重复使用。
XML 架构映射
在 XML Schema 元素中,使用 element
项定义。元素
具有一个必需属性。name
指定在 XML 文档中出现的元素名称。
除了 name
属性 元素
外,还在 表 33.1 “用于定义元素的属性” 中列出的可选属性。
属性 | 描述 |
---|---|
| 指定元素的类型。类型可以是任何 XML 架构原语类型,也可以是合同中定义的任何指定复杂类型。如果没有指定此属性,则需要包含 in-line 类型定义。 |
|
指定元素是否完全保留在文档中。如果 |
|
指定是否在实例文档中使用元素。 |
| 指定可替换为此元素的元素名称。有关使用类型替换的详情,请参考 第 37 章 元素替换。 |
| 为元素指定默认值。有关此属性如何生成代码的信息,请参考 “使用默认值的元素映射 Java”一节。 |
| 为元素指定一个固定值。 |
例 33.1 “简单的 XML 架构元素定义” 显示一个简单的元素定义。
例 33.1. 简单的 XML 架构元素定义
<element name="joeFred" type="xsd:string" />
元素也可以使用在线类型定义定义自己的类型。使用 complexType
元素或 simpleType
元素指定 in-line 类型。指定数据类型是否复杂或简单后,您可以使用每种类型数据的工具定义所需的任何类型的数据。
例 33.2 “使用 In-Line Type 的 XML 架构元素定义” 显示带有 in-line 类型定义的元素定义。
例 33.2. 使用 In-Line Type 的 XML 架构元素定义
<element name="skate"> <complexType> <sequence> <element name="numWheels" type="xsd:int" /> <element name="brand" type="xsd:string" /> </sequence> </complexType> </element>
带有指定类型的元素的 Java 映射
默认情况下,全局定义元素映射到 JAXBElement<T
> 对象,其中模板类由 element
元素的 type
属性的值决定。对于原语类型,模板类使用 “wrapper 类”一节 中描述的打包程序类映射衍生而来。对于复杂类型,生成的 Java 类支持复杂类型用作模板类。
为了支持映射和减轻开发人员对元素的 QName 的不必要的担心,会为每个全局定义的元素生成一个对象工厂方法,如 例 33.3 “全局范围元素的对象工厂方法” 所示。
例 33.3. 全局范围元素的对象工厂方法
public class ObjectFactory { private final static QName _name_QNAME = new QName("targetNamespace", "localName"); ... @XmlElementDecl(namespace = "targetNamespace", name = "localName") public JAXBElement<type> createname(type value); }
例如,例 33.1 “简单的 XML 架构元素定义” 中定义的元素会导致对象工厂方法在 例 33.4 “简单元素的对象工厂” 中显示。
例 33.4. 简单元素的对象工厂
public class ObjectFactory { private final static QName _JoeFred_QNAME = new QName("...", "joeFred"); ... @XmlElementDecl(namespace = "...", name = "joeFred") public JAXBElement<String> createJoeFred(String value); }
例 33.5 “使用全局范围元素” 显示了在 Java 中使用全局范围的元素的示例。
例 33.5. 使用全局范围元素
JAXBElement<String> element = createJoeFred("Green"); String color = element.getValue();
在 WSDL 中使用带有命名类型的元素
如果使用全局范围元素来定义消息部分,则生成的 Java 参数不是 JAXBElement<T>
实例。相反,它被映射到常规的 Java 类型或类。
根据 例 33.6 “WSDL 将元素用作消息部分” 中显示的 WSDL 片段,生成的方法具有类型为 String
的参数。
例 33.6. WSDL 将元素用作消息部分
<?xml version="1.0" encoding=";UTF-8"?> <wsdl:definitions name="HelloWorld" targetNamespace="http://apache.org/hello_world_soap_http" xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://apache.org/hello_world_soap_http" xmlns:x1="http://apache.org/hello_world_soap_http/types" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <wsdl:types> <schema targetNamespace="http://apache.org/hello_world_soap_http/types" xmlns="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified"><element name="sayHi"> <element name="sayHi" type="string"/> <element name="sayHiResponse" type="string"/> </schema> </wsdl:types> <wsdl:message name="sayHiRequest"> <wsdl:part element="x1:sayHi" name="in"/> </wsdl:message> <wsdl:message name="sayHiResponse"> <wsdl:part element="x1:sayHiResponse" name="out"/> </wsdl:message> <wsdl:portType name="Greeter"> <wsdl:operation name="sayHi"> <wsdl:input message="tns:sayHiRequest" name="sayHiRequest"/> <wsdl:output message="tns:sayHiResponse" name="sayHiResponse"/> </wsdl:operation> </wsdl:portType> ... </wsdl:definitions>
例 33.7 “使用全局元素作为部分的 Java 方法” 显示为 sayHi
操作生成的方法签名。
例 33.7. 使用全局元素作为部分的 Java 方法
String
sayHi
String
in
使用 in-line 类型进行元素映射的 Java 映射
当使用 in-line 类型定义元素时,它会按照与用于将其他类型映射到 Java 相同的规则映射到 Java。简单类型的规则在 第 34 章 使用简单类型 中进行了描述。第 35 章 使用复杂类型 中描述了复杂类型的规则。
当为带有在线类型定义的元素生成 Java 类时,生成的类使用 @XmlRootElement
注释进行解码。@XmlRootElement
注释有两个有用的属性: name
和 namespace
。这些属性在 表 33.2 “@XmlRootElement Annotation 的属性” 中进行了描述。
属性 | 描述 |
---|---|
|
指定 XML Schema |
| 指定定义元素的命名空间。如果在目标命名空间中定义了此元素,则不会指定属性。 |
如果元素满足以下一个或多个条件,则不会使用 @XmlRootElement
注释:
-
元素的
nillable
属性设为true
元素是替换组的 head 元素
有关替换组的详情,请参考 第 37 章 元素替换。
抽象元素的 Java 映射
当元素的 abstract
属性设置为 true
时,不会生成实例化类型的实例的对象工厂方法。如果使用在线类型定义元素,则生成支持 in-line 类型的 Java 类。
使用默认值的元素映射 Java
当使用元素 的默认
属性时,defaultValue
属性将添加到生成的 @XmlElementDecl
注释中。例如,例 33.8 “使用默认值的 XML 架构元素” 中定义的元素会导致对象工厂方法在 例 33.9 “具有默认值的元素的对象工厂方法” 中显示。
例 33.8. 使用默认值的 XML 架构元素
<element name="size" type="xsd:int" default="7"/>
例 33.9. 具有默认值的元素的对象工厂方法
@XmlElementDecl(namespace = "...", name = "size", defaultValue = "7")
public JAXBElement<Integer> createUnionJoe(Integer value) {
return new JAXBElement<Integer>(_Size_QNAME, Integer.class, null, value);
}