在 XML 结构中,通配符 <xsd:any> 元素允许使用该结构未指定的元素扩展复杂类型。当复杂类型的内容确实不需要在结构中定义时,使用 <xsd:any> 元素也会非常有用。例如,请考虑以下情况:服务操作可能会接收多种类型的订单 XML 文档,并且每个订单都定义了不同的结构。在这种情况下,将元素订单文档类型描述为服务接口中的 <any> 是很有用的。这样会使端点更为通用。这还意味着服务实现代码必须确定它接收的 xml 文档的类型,并对其进行正确处理。使用 <any> 会使服务操作更为通用,因此您的代码必须能够处理它。在代码示例 1 中的 WSDL 文件中,请注意有一个包括 <any> 元素的已定义类型 submitPO,它在一定程度上将 <any> 封装在了其他元素声明中。然后在服务接口中使用此 submitPO 类型作为提交订单的操作(请注意,元素名称 submitPO 和操作名称 submitPO 是相同的,这只是因为 WSDL 使用了指定这些名称匹配约定的封装样式)。在此服务中,所接收的文档可以在 XML 中具有任何元素。
<complexType name="submitPO">
<sequence>
<any/>
</sequence>
</complexType>
<element name="submitPO" type="tns:submitPO"/>
</schema>
</types>
<message
name="AnyPurchaseOrderServiceSEI_submitPO">
<part name="parameters" element="tns:submitPO"/>
</message>
...
<portType
name="AnyPurchaseOrderServiceSEI">
<operation name="submitPO">
<input
message="tns:AnyPurchaseOrderServiceSEI_submitPO"/>
...
</operation>
</portType>
代码示例 1:显示将 <any> 用作服务操作输入参数的 WSDL 代码片段
在 JAX-RPC 中,当使用 xsd:any 结构类型元素表示元素通配符时,复杂类型的映射将映射到 JavaBeans[TM] 组件。如果 <any> 元素在 maxOccurs 等于 1 时,则会出现一个名为 _any 的附加属性映射到 javax.xml.soap.SOAPElement(如果 maxOccurs 大于 1,则它会映射到 javax.xml.soap.SOAPElement 的数组)。此外,在 JAX-RPC 中,如果 XML 结构类型没有标准的 Java 映射,则会考虑具有类型表示的消息部分并将它映射为 XML 文档片段。XML 到 Java 的映射使用接口 javax.xml.soap.SOAPElement 来表示 wsdl:operation 元素的 Java 映射中的类型消息部分。因此,如果从 WSDL 文件(如代码示例 1 所示,将 <any> 作为被接收的文档的类型)生成 Java 接口,则 Java 接口会具有 SubmitPO 类型的封装类,如代码示例 2 所示。在这种情况下,此接口的 Java 实现将需要为 SubmitPO 参数调用 getter 方法 get_any()
,以获取封装在内部的 SOAPElement。使用这一额外步骤进行调用会产生一些不方便,但不会带来很大的麻烦。
public interface
AnyPurchaseOrderServiceSEI extends Remote {
public SubmitPOResponse submitPO(SubmitPO
parameters) throws
InvalidPOException,
java.rmi.RemoteException;
}