原文http://www.ibm.com/developerworks/cn/webservices/ws-array/index.html
一种帮助区别零数组和空数组的 XML Schema 模式
简介: 一些程序依赖于零数组(null array)和空数组(empty array)之间的差别。在 XML Schema 中数组的表示却没有这样的差别。您能不能采取办法来克服 XML 的这个特征不利的方面呢?本文将给您展示一种解决这种问题的方法。
当使用 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 模式来等价地获取这种差别,但是这个模式没有得到标准组织很好的认可,仅当绝对必须时才应该使用。