第 33 章 使用 XML 元素
摘要
XML 架构元素用于在 XML 文档中定义元素实例。元素在 XML 架构文档的全局范围中定义,或者被定义为复杂类型的成员。在全局范围中定义时,Apache CXF 会将它们映射到一个 JAXB 元素类,从而更轻松地操作它们。
概述
XML 文档中的一个元素实例由 XML 架构文档中的全局范围 元素
定义,以便让 Java 开发人员更轻松地与元素一起工作,Apache CXF 将全局范围元素映射到一个特殊的 JAXB 元素类,或生成的 Java 类匹配其内容类型。
映射元素的方式取决于该元素是否使用 type 所引用的命名 类型
定义,或者使用内类型定义来定义该元素。使用行类型定义定义的元素映射到 Java 类。
建议使用命名类型定义元素,因为示例中的其他元素不重复使用行类型。
XML 架构映射
在 XML 架构中,利用 元素元素
来定义。元素
具有一条必需属性。name
指定在 XML 文档中出现的元素的名称。
除了 name
属性 元素
外,您还可以在 表 33.1 “用于定义元素的属性” 中列出的可选属性。
属性 | 描述 |
---|---|
| 指定元素的类型。类型可以是任何 XML 架构原语类型,也可以是合同中定义的任何指定复杂类型。如果没有指定此属性,则需要在行类型定义中包含。 |
|
指定某个元素是否可完全离开文档。如果 |
|
指定实例文档中是否可以使用元素。 |
| 指定可用此元素替换的元素的名称。有关使用类型替换的详情,请参考 第 37 章 element Substitution。 |
| 指定元素的默认值。有关此属性影响代码生成方式的详情,请参考 “带有默认值的元素的 Java 映射”一节。 |
| 为元素指定固定值。 |
例 33.1 “简单 XML 架构元素定义” 显示了一个简单的元素定义。
例 33.1. 简单 XML 架构元素定义
<element name="joeFred" type="xsd:string" />
元素也可以使用内行类型定义来定义自己的类型。in-line 类型通过 complexType
元素或 simpleType
元素来指定。指定数据类型是否比较复杂或简单,您可以使用每种数据类型可用的工具定义任何类型的数据。
例 33.2 “XML 架构元素定义(in-line)类型” 显示包含行类型定义的元素定义。
例 33.2. XML 架构元素定义(in-line)类型
<element name="skate"> <complexType> <sequence> <element name="numWheels" type="xsd:int" /> <element name="brand" type="xsd:string" /> </sequence> </complexType> </element>
包含指定类型的元素的 Java 映射
默认情况下,全局定义的元素映射到 JAXBElement<T
> 对象,其中 template 类由 element 元素
的 type
属性的值决定。对于 primitive 类型,模板类使用 “打包程序类”一节 中描述的打包程序类映射进行派生。对于复杂的类型,生成的 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 方法
字符串中的
字符串
具有内线类型的元素的 Java 映射
使用行类型定义元素时,它将按照与用于将其他类型映射到 Java 的规则相同的规则映射到 Java。简单类型的规则介绍了 第 34 章 使用简单类型。第 35 章 使用复杂类型 中描述了复杂类型的规则。
为带有行类型定义的元素生成 Java 类时,生成的类将被 @XmlRootElement
注释进行解码。@XmlRootElement
注释有两个有用的属性: name
和 namespace
。这些属性在 表 33.2 “@XmlRootElement 注解的属性” 中所述。
属性 | 描述 |
---|---|
|
指定 XML Schema |
| 指定定义元素的命名空间。如果此元素在目标命名空间中定义,则不指定该属性。 |
如果元素满足一个或多个条件,则不会使用 @XmlRootElement
注解:
-
元素的
nillable
属性被设置为true
元素是替换组的头元素
有关替换组的更多信息,请参阅 第 37 章 element Substitution。
抽象元素的 Java 映射
当元素的 abstract
属性设为 true
时,不会生成用于实例化类型的实例的对象工厂方法。如果该元素使用内行类型定义,则将生成支持内类型的 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);
}