ヌルのJava™ beanフィールドをXMLにマップするときには、XMLでフィールドに相当するものでヌル値を表現します。このヒントでは、そのためのさまざまな方法を調べて比較します。

Russell Butek (butek@us.ibm.com), Developer, EMC

Russell Butekは、IBM WebSphereのWebサービス・エンジンの開発者の一人です。JSR (JAX-RPC Java Specification Request) エキスパート・グループのIBM代表でもあります。Apache AXISのSOAPエンジンの実装にも関与し、AXIS 1.0でJAX-RPC 1.0対応を行いました。以前はIBMのCORBA ORBの開発者であり、そして、・・・ポータブル・インターセプター作業部会(ここで議長を務める)、コア作業部会、インターオペラビリティ作業部会・・・など、数々のOMG (Object Management Group) 作業部会でIBM代表を務めました。



2005年 8月 09日

はじめに

Java beanにはプロパティー、すなわちフィールドがあります。これらのフィールドは、プリミティブ型でない限り、ヌルになることがあります。Java beanをXMLにマップすると、これらのフィールドは要素または属性になります。修飾されていない要素および属性がヌル値を持つことはできません(Javaプリミティブ型に相当するものと考えることができます。どちらもヌルにはなりません)。XMLの属性および要素を修飾して、それらのインスタンスがヌル(または少なくとも論理的にヌルに等しいもの)になりえるようにするには、さまざまな方法があります。

  • 属性の場合
    • 属性use="optional"を使用する
  • 要素の場合
    • 属性nillable="true"を使用する
    • または、属性minOccurs="0"を使用する

このヒントでは、これらの選択肢のそれぞれの詳細と派生的効果を説明します。


要素対属性

ヌルの表現について述べる前に、なぜオブジェクト・フィールドとして要素または属性を使用した方がよいかを考えておきましょう。最初に考えなければならないのは、フィールドの型です。属性では単純な型しか使えません。したがって、複雑な型がある場合、選択の余地はありません。要素を使用しなければなりません。しかし、単純な型しかない場合は、属性と要素のどちらを使うべきでしょうか。たとえば、リスト1の構造の場合、attrFieldとelemFieldのどちらがよいでしょうか。

リスト1. AttributeOrElementスキーマ
<complexType name="AttributeOrElement">
  <sequence>
    <element name="elemField" type="xsd:int"/>
  </sequence>
  <attribute name="attrField" type="xsd:int"/>
</complexType>

リスト1のスキーマのインスタンスについては、リスト2を見てください。

リスト2. AttributeOrElementのインスタンス
<attributeOrElement attrField="5">
  <elemField>5</elemField>
</attributeOrElement>

属性フィールドは要素フィールドよりもインスタンス内に占めるスペースが明らかに少なくて済むので、属性を含んでいるXMLではSOAPメッセージが小さくなり、したがって、転送に必要な時間も短くなります。そのため、属性の方が要素よりよいと考えるのは妥当なように思えます。しかし、スキーマを少しでも扱ったことがある人ならば、属性が使われているのをあまり見ないことに気づいたかもしれません。なぜでしょう。実際のところはわかりませんが、いくつか考えられることがあります。

  • 複雑な型には要素を使用しなければならないので、一貫性のためには、単純な型にも要素を使用すべきです。結局、スキーマの見た目が単純になります。
  • ドキュメント/リテラルでラップされたパターンの場合、ラッパー要素のcomplexTypeには属性は含まれません(参考文献の「Which style of WSDL should I use?」を参照)。ラッパー要素内のこのパラメーター・リストは要素にしかできないので、一貫性のために、すべてのcomplexTypeリストを要素にすべきです。
  • 属性には順序がなく、要素には順序があるので(<all>タグを使用しない限り)、属性の解析の方が要素の解析よりもコストがかかるでしょう。(ただし、高度なXMLパーサーでは実際には問題にならないのではないかと思います。)

したがって、単純さのためには、スループット・パフォーマンスが問題でない限り、要素を使うことをお勧めします。パフォーマンスが重要なときには、属性によってパフォーマンスが改善されるかどうかテストすればよいでしょう。

では、ヌル値に話を進めましょう。


ヌル属性

すでに述べたように、属性をオプションにすることによって、属性を論理的にヌル可能にできます。リスト3のヌル可能属性を持つスキーマとリスト4のインスタンスを見てください。1つはフィールドに値を持ち、もう1つは値を持ちません。

リスト3. TypeWithNullAttributeスキーマ
<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/>

ヌル属性のスキーマ宣言は非常に簡単であることがわかります。ヌル属性のインスタンスも非常に簡単です。単に、ないのです。


ヌル要素

属性はまれにしか使われず、要素の方がはるかに一般的なので、ヌル要素に話を進めましょう。要素でヌル値を表現するには2つの方法があります。すなわち、属性nillable="true"を使うか、minOccurs="0"を使います。リスト5は、TypeWithNullElementsのスキーマを示しています。これは、それぞれのスタイルのヌル可能フィールドについて1つの要素を含んでいます。

リスト5. TypeWithNullElementsスキーマ
<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のヌル値は、値のためのプレースホルダーを持つと述べました。どんなときにプレースホルダーが必要でしょうか。一例としては、各配列エントリーが潜在的にヌルになりうる配列があります。たとえば、4要素の配列があり、値が{0, null, 1, null}であるとします。minOccursElem要素のインスタンスを使用して、この配列を表現するにはどうしたらよいでしょう。答え:できません。上記の4要素配列と値が{0, 1}である2要素配列を区別する手段はありません。minOccurs="0"要素を使用した場合、null要素のプレースホルダーはありません。したがって、このようなときにはnillable="true"要素を使用しなければなりません。リスト7は、このような配列のスキーマを示し、リスト8は、{0, null, 1, null}のXMLインスタンスを示しています。

(配列とヌル値に関するちょっとした工夫については、参考文献の「Array Gotcha」を参照してください。)

リスト7. ヌル可能配列要素のスキーマ
<complexType name="nullableElementArray">
  <sequence>
    <element name="elem" type="int" maxOccurs="4" nillable="true"/>
  </sequence>
</complex
Type>
リスト8. ヌル可能配列要素のXMLインスタンス
<nullableElementArray>
  <elem>1</elem>
  <elem xsi:nil="true"/>
  <elem>2</elem>
  <elem xsi:nil="true"/>
</nullableElement>

まとめ

XMLスキーマでヌル・フィールドを表現するには、オプション属性、minOccurs="0"要素、nillable="true"要素の3つの方法があります。状況に応じて、これらを使い分けてください。単純なヌル可能型がある場合はオプション属性を使ってください。複雑なヌル可能型があり、できるだけスペースを使いたくない場合は、minOccurs="0"を使ってください。ヌル値にプレースホルダーが必要な場合は(たとえば、配列内に現れるときなど)、nillable="true"要素を使ってください。

参考文献

コメント

developerWorks: サイン・イン

必須フィールドは(*)で示されます。


IBM ID が必要ですか?
IBM IDをお忘れですか?


パスワードをお忘れですか?
パスワードの変更

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


お客様が developerWorks に初めてサインインすると、お客様のプロフィールが作成されます。会社名を非表示とする選択を行わない限り、プロフィール内の情報(名前、国/地域や会社名)は公開され、投稿するコンテンツと一緒に表示されますが、いつでもこれらの情報を更新できます。

送信されたすべての情報は安全です。

ディスプレイ・ネームを選択してください



developerWorks に初めてサインインするとプロフィールが作成されますので、その際にディスプレイ・ネームを選択する必要があります。ディスプレイ・ネームは、お客様が developerWorks に投稿するコンテンツと一緒に表示されます。

ディスプレイ・ネームは、3文字から31文字の範囲で指定し、かつ developerWorks コミュニティーでユニークである必要があります。また、プライバシー上の理由でお客様の電子メール・アドレスは使用しないでください。

必須フィールドは(*)で示されます。

3文字から31文字の範囲で指定し

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


送信されたすべての情報は安全です。


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=SOA and web services, XML
ArticleID=245199
ArticleTitle=Webサービスのヒント:XML Schemaでのヌルの表現
publish-date=08092005