XML Schema 中空值的表示

当你将空的 Java™ Bean 映射到 XML 时怎么在对应的 XML 中表示空值。本文探究和比较进行这种表示的许多方式。

  Introduction

  Java Bean 有属性或字段。如果这些字段不是基元类型的,则他们可能是空的。当你将 Java Bean 映射到 XML 时,这些字段就变成了元素或属性。未经修饰的元素和属性不能具有空值(你大致能把他们看作是对应的 Java 基元类型??二者都不能为空)。有许多修饰 XML 属性和元素的方法,采用这些方法能使他们的实例为空(或至少在逻辑上等同于空值)。

  对于属性:

使用属性 use="optional"

  对于元素:

使用属性 nillable="true"
或使用属性 minOccurs="0"

  本文描述上面的每一种选择的细节和可能出现的情况。

  元素和属性

  在研究空表示之前,首先确定可能需要在对象字段中使用元素和属性的原因。需要考虑的第一件事是字段的类型。你只能在属性中使用简单的类型。因 此,如果你使用的是复杂类型,则没有选择的余地;必须 使用元素。然而,如果你使用的是简单类型,那么你应该选择属性还是元素呢?例如,给定的清单 1 中的结构,哪一个更好?attrField 还是 elemField?

  清单 1. AttributeOrElement Schema

<complexType name="AttributeOrElement">
  <sequence>
    <element name="elemField" type="xsd:int"/>
  </sequence>
  <attribute name="attrField" type="xsd:int"/>
</complexType>

  让我们看一看清单 2,他是清单 1 中的 Schema 的实例。

  清单 2. AttributeOrElement 的实例

<attributeOrElement attrField="5">
  <elemField>5</elemField>
</attributeOrElement>

  显然,在该实例中,属性字段占用的空间比元素字段小,因此使用包含属性的 XML 的 SOAP 消息的传输时间会更短。看起来假定属性比元素更好似乎是合理的。不过如果你和 Schema 打过一段时间的交道,你可能非常少看到使用属性。这是为什么呢?我实在无法告诉你具体的原因,不过我有一些想法:

  由于你必须 在复杂类型中使用元素,因此从一致性方面考虑,你也应该将元素用于简单类型。最后得到的是看起来更简单的 Schema。

  文件/文字包装的模式规定包装程式元素的 complexType 不包含属性。由于包装程式元素中的这一参数列表只能是元素,因此从一致性方面考虑,所有的 complexType 列表都应该是元素。

  由于属性没有顺序,而元素有顺序(除非使用 标记),因此解析属性的开销可能比解析元素高一些(不过,我怀疑这对于复杂的 XML 解析器真的不是个问题)。

  所以为了简单起见,我建议坚持使用元素,除非吞吐量性能是需要关注的重要问题,在这种情况下,你能测试属性是否能改进性能。

  目前让我们讨论空值。

  空属性

  正如我已提到的,你能通过让属性可选来使其逻辑上可为空值。请参见清单 3 中带有可为空值的属性的 Schema,及清单 4 中的实例??一个字段中包含值的实例和一个字段中不包含值的实例。

  清单 3. TypeWithNullAttribute Schema

<complexType name="TypeWithNullAttribute">
  <attribute name="attrField" type="xsd:int" use="optional"/>
</complexType>

  清单 4. TypeWithNullAttribute 的实例

Attribute with a value:

<typeWithNullAttribute attrField="5"/>

Attribute passed as null:

<typeWithNullAttribute/>  

  能看出,空属性的 Schema 声明相当简单。空属性的实例也非常简单??不过这里不进行具体说明。

空元素

  由于非常少使用属性,而更普遍地使用元素,因此我们转到空元素。有两种通过元素表示空值的方法:使用属性 nillable="true" 或使用属性 minOccurs="0"。Listing 5 展示了 TypeWithNullElements 的 Schema,他为每种可为空值的字段样式提供一个元素。

  清单 5. TypeWithNullElements 的 Schema

<complexType name="TypeWithNullElements">
  <sequence>
    <element name="nillableElem" nillable="true" type="int"/>
    <element name="minOccursElem" minOccurs="0" type="int"/>
  </sequence>
</complexType>
 

  清单 6 展示了 TypeWithNullElements 的实例,首先出现的是常规值,接下来的是空值。

  清单 6. TypeWithNullElements 的实例

Elements with values:

<typeWithNullElements>
  <nillableElem>5</nillableElem>
  <minOccursElem>5</minOccursElem>
</typeWithNullElements>

Elements with null values:

<typeWithNullElements>
  <nillableElem xsi:nil="true"/>
</typeWithNullElements>
 

  和可选的属性相同,具有 minOccurs="0" 属性的元素的值为空,不过没有出目前 XML 实例中。和使用属性 nillable="true" 定义的元素相比,此元素在消息大小方面的代价肯定要低一些。即使 nillableElem 的值为空,不过他仍然有值占位符,指示其实际为空。

  nillable="true" 何时有用

  非常显然,minOccursElem 比 nillableElem 好一些,不过为什么始终需要使用 nillableElem 呢?我已提示过。前面我讲到,nillableElem 的空值有值占位符。在哪里你可能需要占位符?这样的一个例子就是数组,其中的每个数组条目都可能为空。例如,设想一个数组有四个元素,其值为 {0, null, 1, null}。你怎么使用 minOccursElem 元素的实例表示该数组呢?回答是:你不能这样做。无法区分上述四个元素组成的数组和其值为 {0, 1} 的两个元素组成的数组。如果使用 minOccurs="0" 元素,则没有空元素占位符。因此在这种情况下,你必须使用 nillable="true" 元素。清单 7 展示了这样的一个数组的 Schema,清单 8 展示了 {0, null, 1, null} 的 XML 实例。

  清单 7. 可为空值的数组元素的 Schema

<complexType name="nullableElementArray">
  <sequence>
    <element name="elem" type="int" maxOccurs="4" nillable="true"/>
  </sequence>
</complexType>
 

  清单 8. 可为空值的数组元素的 XML 实例

<nullableElementArray>
  <elem>1</elem>
  <elem xsi:nil="true"/>
  <elem>2</elem>
  <elem xsi:nil="true"/>
</nullableElement>

  总结

  有三种在 XML Schema 中表示空字段的方法:可选的属性、minOccurs="0" 元素和 nillable="true" 元素。使用上面各个元素的情况如下:如果是可为空值的简单类型,则使用可选的属性;如果是可为空值的复杂类型,并且希望他占用最小的空间,则使用 minOccurs="0" 元素;如果空值必须有占位符(例如当其在数组中出现时),则使用 nillable="true" 元素。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值