当使用 Web 服务时,常常总是假设所有在编程语言中能够做的事情也同样能够在 XML 做到。在很多情况下并不是这样的。这里介绍的技巧用于处理其中的一个情况:一个为“零”的数组和一个没有元素的数组之间的差别。
大部分编程语言,比如说 Java 语言,都有数组的概念:相似元素的有序集合。同样,XML
也有相似元素的有序集合: 一个具有
maxOccurs 属性且该属性值大于1的 XML schema 元素。所以,有理由说 Java 语言中的相似元素的有序集合能够很好地映射到 XML 中的相似元素的有序集合。
清单 1 中定义了一个
complexType ,其中就包含有这样一个 XML schema “数组”。
<complexType name="bean">
<sequence>
<element name="name" type="xsd:string"/>
<element name="array" minOccurs="0" maxOccurs="unbounded"
nillable="true" type="xsd:int"/>
</sequence>
</complexType>
|
严格来说,这个 XML “数组”并不是一个数组。它是一个有 出现约束的元素,也就是说这个元素被定义出现特定的次数,在这里可以是 0 次或更多次。听起来这非常像一个数组,对于大多数的意图和目的,它也确实是一个数组。但是这一映射并不完美。您应该意识到这个缺点,这样以来您就不会被它们意外地诱入陷阱。
依据 JAX-RPC 的映射规则,
清单 1 中的
complexType 将变成
清单 2中的 Java bean (实际上,这个 bean 将有 getters 和 setters,但是在这个讨论中我们将简化它)。
public class Bean {
public java.lang.String name;
public java.lang.Integer[] array;
}
|
(注意:这个
Bean 的数组变量是一个
java.lang.Integer 数组, 不是一个
int 数组。XML schema 中的数组元素是可为“零”的(nillable)。Java
int 不能为“零”(null)。
java.lang.Integer 可以为“零”(null)。所以在这一映射中我们使用
java.lang.Integer 。)
表 1显示许多 Java Bean 的实例和相应的 XML 实例之间映射的例子。第一行是 Java 表示;第二行是相应的 XML 表示。
请注意 表 1 中有一个显而易见的事实——它是这个技巧的主题——就是一个 Java 数组的空(empty)实例和一个 Java 数组的“零”(null)实例都映射到相同的 XML 实例。如果您正依赖两者的差别,这确实不是一个好办法。
很容易落入的一个陷阱就是猜测在表的第二列中用 XML 表示在 Bean 中的“零”(null)数组。但是,正如我们希望的,在表中已经显示,它真正表示的是含有单一元素的数组,元素的值为“零”(null),而不是一个“零”(null)数组。
当然!已经知道的事情是在大多数编程语言中的数组其实是由两部分组成的:数组的内容和数组本身——如果您喜欢,也可以这样形容,内容和包在外面的包装。一个 XML “数组”只是元素的列表,而没有“包装”。
所以,解决的方法很简单:为数组创建一个“包装”,正如 清单 3所示。
<complexType name="arrayWrapper">
<sequence>
<element name="el" nillable="true" maxOccurs=
"unbounded" minOccurs="0" type="xsd:int"/>
</sequence>
</complexType>
<complexType name="bean">
<sequence>
<element name="name" type="xsd:string"/>
<element name="array" nillable="true" type="
tns:arrayWrapper"/>
</sequence>
</complexType>
|
表 2 是对于这个 XML Schema 的数组示例表格。
正如您可以看到的,
arrayWrapper complexType
的空实例和零实例彼此之间是有差别的。
这一解决方法并不是“百宝丹”。首先,它比用简单的
minOccurs /
maxOccurs
表示数组要复杂得多。其次,这个 XML Schema
不是包含一个数组的简单 Bean,其实它看起来像这样一个 Bean,在这个
Bean 中包含一个含有数组的 Bean;如果您用自己喜欢的 JAX-RPC
WSDL-to-Java 工具将这个 XML Schema 映射到 Java
编程,就很可能以它结束。只有在标准组织适当地认可和映射这个包装的数组模式之后,您才能应用这一解决方法(如果您确实需要区别零数组和空数组的话)。
XML “数组”并不是编程语言意义上的真正的数组。XML 不区分零数组(null array)和空数组(empty array)。您可以遵循一种 XML Schema 模式来等价地获取这种差别,但是这个模式没有得到标准组织很好的认可,仅当绝对必须时才应该使用。
- 您可以参阅本文在 developerWorks 全球站点上的
英文原文.
- 获得早期版本的
WebSphere Application Server Technology for Developers, version 6.0,它支持 J2EE 1.4。
- 阅读
Web
服务描述语言(Web Services Description Language,WSDL)1.1,它是
WSDL 的规范。
- 阅读
XML Schema Primer,它是 XML Schema
规范的入门读物。
- 获得
IBM WebSphere SDK for Web Services(WSDK)Version 5.1,它是用于创建、发现、调用和测试 Web 服务的集成工具包。从这个链接您能够下载到 WSDK 5.1
和许多教程。
-
Java API for XML-Based RPC (JAX-RPC) Downloads & Specifications
提供指向 JAX-RPC 1.1 规范本身以及 javadocs、类文件和 Sun 的 JAX-RPC 参考实现的链接。