Web 服务编程技巧与窍门: 数组局限性 -- 零数组(null)与空数组(empty)

原文http://www.ibm.com/developerworks/cn/webservices/ws-array/index.html

一种帮助区别零数组和空数组的 XML Schema 模式

Russell Butek ( butek@us.ibm.com), 软件工程师, IBM
Richard Scheuerle ( scheu@us.ibm.com), 软件工程师, IBM

 

简介: 一些程序依赖于零数组(null array)和空数组(empty array)之间的差别。在 XML Schema 中数组的表示却没有这样的差别。您能不能采取办法来克服 XML 的这个特征不利的方面呢?本文将给您展示一种解决这种问题的方法。

 

 

发布日期: 2004 年 1 月 01 日
级别: 初级
访问情况 436 次浏览
建议: 0 (添加评论)

1 star 2 stars 3 stars 4 stars 5 stars 平均分 (共 0 个评分 )

 

当使用 Web 服务时,常常总是假设所有在编程语言中能够做的事情也同样能够在 XML 做到。在很多情况下并不是这样的。这里介绍的技巧用于处理其中的一个情况:一个为“零”的数组和一个没有元素的数组之间的差别。

XML 数组

大部分编程语言,比如说 Java 语言,都有数组的概念:相似元素的有序集合。同样,XML 也有相似元素的有序集合: 一个具有 maxOccurs 属性且该属性值大于1的 XML schema 元素。所以,有理由说 Java 语言中的相似元素的有序集合能够很好地映射到 XML 中的相似元素的有序集合。 清单 1 中定义了一个 complexType ,其中就包含有这样一个 XML schema “数组”。

清单 1. 包含一个“数组”的 complexType


<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,但是在这个讨论中我们将简化它)。

清单 2. 包含一个数组的 bean。


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所示。

清单 3. 包含包装的数组的 bean


								
        <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 的空实例和零实例彼此之间是有差别的。

包装的数组的映射

WebSphere Application Server 6.0 将认可这种特殊的包装的数组模式。代替生成额外的 Java Bean,它将简单地生成您在 清单 2 中所看到的 Bean。Microsoft 的 .NET 也认可这种包装的数组模式,并且生成友好的 C# 代码。

这一解决方法并不是“百宝丹”。首先,它比用简单的 minOccurs / maxOccurs 表示数组要复杂得多。其次,这个 XML Schema 不是包含一个数组的简单 Bean,其实它看起来像这样一个 Bean,在这个 Bean 中包含一个含有数组的 Bean;如果您用自己喜欢的 JAX-RPC WSDL-to-Java 工具将这个 XML Schema 映射到 Java 编程,就很可能以它结束。只有在标准组织适当地认可和映射这个包装的数组模式之后,您才能应用这一解决方法(如果您确实需要区别零数组和空数组的话)。


总结

XML “数组”并不是编程语言意义上的真正的数组。XML 不区分零数组(null array)和空数组(empty array)。您可以遵循一种 XML Schema 模式来等价地获取这种差别,但是这个模式没有得到标准组织很好的认可,仅当绝对必须时才应该使用。


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值