第36章 ワイルドカードタイプの使用
概要
スキーマ作成者がバインディング要素または属性を定義された型に延期したい場合があります。このような場合、XML スキーマはワイルドカードプレースホルダーを指定するための 3 つのメカニズムを提供します。これらはすべて、XML スキーマ機能を保持する方法で Java にマップされます。
36.1. 任意の要素の使用
概要
XML Schema any
要素は、複雑なタイプ定義にワイルドカードの配置ホルダーを作成するために使用されます。XML スキーマ any
要素に対して XML 要素がインスタンス化されると、有効な XML 要素を使用できます。any
要素は、インスタンス化された XML 要素の名前に制約をかけません。
たとえば、例36.1「任意の要素で定義された XML スキーマタイプ」 で定義された複合型が与えられた場合 例36.2「任意の要素を含む XML ドキュメント」 に示す XML 要素のいずれかをインスタンス化できます。
例36.1 任意の要素で定義された XML スキーマタイプ
<element name="FlyBoy"> <complexType> <sequence> <any /> <element name="rank" type="xsd:int" /> </sequence> </complexType> </element>
例36.2 任意の要素を含む XML ドキュメント
<FlyBoy> <learJet>CL-215</learJet> <rank>2</rank> </element> <FlyBoy> <viper>Mark II</viper> <rank>1</rank> </element>
XML Schema any
要素は、Java オブジェクト
オブジェクトまたは Java org.w3c.dom.Element
オブジェクトにマッピングされます。
XML スキーマでの指定
シーケンスの複雑な型や複雑なタイプを定義するときに、any
要素を使用できます。多くの場合、any
要素は空の要素です。ただし、annotation
要素を子として取ることができます。
表36.1「XML スキーマの属性任意の要素」 は、any
要素の属性を記述します。
属性 | 説明 |
---|---|
| XML ドキュメントで要素をインスタンス化するために使用できる要素の名前空間を指定します。有効な値は、以下の通りです。
|
|
要素のインスタンスが親要素に表示される最大回数を指定します。デフォルト値は |
|
要素のインスタンスが親要素に表示される最小回数を指定します。デフォルト値は |
| 任意の要素をインスタンス化するために使用される要素を検証する方法を指定します。有効な値は以下のとおりです。
|
例36.3「任意の要素で定義された複合型」に、any
要素で定義された複合型を示します。
例36.3 任意の要素で定義された複合型
<complexType name="surprisePackage"> <sequence> <any processContents="lax" /> <element name="to" type="xsd:string" /> <element name="from" type="xsd:string" /> </sequence> </complexType>
Java へのマッピング
XML スキーマの any
要素により、any
という名前の Java プロパティーが作成されます。プロパティーには、ゲッターメソッドとセッターメソッドが関連付けられています。作成されるプロパティーのタイプは、要素の processContents
属性の値によって異なります。any
要素の processContents
属性が skip
に設定されている場合、要素は org.w3c.dom.Element
オブジェクトにマッピングされます。processContents
属性の値がそれ以外の場合、any
要素は Java Object
オブジェクトにマッピングされます。
生成されたプロパティーは @XmlAnyElement
アノテーションで禁止されています。このアノテーションには、データをマーシャリングする際のランタイムに指示するオプションの lax
プロパティーがあります。デフォルト値は false
で、データを org.w3c.dom.Element
オブジェクトに自動的にマーシャリングするようにランタイムに指示します。lax
を true
に設定: ランタイムが、データを JAXB タイプにマーシャリングしようとします。any
要素の processContents
属性が skip
に設定されている場合は、lax
プロパティーはデフォルト値に設定されます。processContents
属性の他のすべての値の場合、lax
は true
に設定されます。
例36.4「任意の要素を持つ Java クラス」 で定義された複合型がどのように定義されているかを示し、例36.3「任意の要素で定義された複合型」 Java クラスにマップされます。
例36.4 任意の要素を持つ Java クラス
public class SurprisePackage { @XmlAnyElement(lax = true) protected Object any; @XmlElement(required = true) protected String to; @XmlElement(required = true) protected String from; public Object getAny() { return any; } public void setAny(Object value) { this.any = value; } public String getTo() { return to; } public void setTo(String value) { this.to = value; } public String getFrom() { return from; } public void setFrom(String value) { this.from = value; } }
マーシャリング
any
要素の Java プロパティーにその lax
が false
に設定されているか、プロパティーが指定されていない場合、ランタイムは XML データの JAXB オブジェクトへの解析を試行しません。データは常に DOM Element
オブジェクトに保存されます。
any
要素の Java プロパティーの lax
が true
に設定されている場合、ランタイムは XML データを適切な JAXB オブジェクトにマーシャリングしようとします。ランタイムは、次の手順を使用して適切な JAXB クラスを識別しようとします。
- XML 要素の要素タグをランタイムに認識されている要素のリストと照合します。一致するものが見つかった場合、ランタイムは XML データを要素の適切な JAXB クラスにマーシャリングします。
-
XML 要素の
xsi:type
属性をチェックします。一致するものが見つかった場合、ランタイムは XML 要素をそのタイプの適切な JAXB クラスにマーシャリングします。 -
一致するものが見つからない場合は、XML データを DOM
Element
オブジェクトにマーシャリングします。
通常、アプリケーションのランタイムは、そのコントラクトに含まれるスキーマから生成されたすべてのタイプを認識しています。これには、コントラクトの wsdl:types
要素で定義された型や、インクルージョンによってコントラクトに追加されたデータ型、他のスキーマのインポートによってコントラクトに追加されたデータ型が含まれます。「ランタイムマーシャラーへのクラスの追加」 で説明される @XmlSeeAlso
アノテーションを使用して、追加の型をランタイムを認識させることもできます。
アンマーシャリング
any
要素の Java プロパティーの lax
が false
に設定されているか、プロパティーが指定されていない場合、ランタイムは DOM Element
オブジェクトだけを受け入れます。他のタイプのオブジェクトを使用しようとすると、マーシャリングエラーが発生します。
any
要素の Java プロパティーの lax
が true
に設定されている場合、ランタイムは Java データ型とそれらが表す XML スキーマ構造との間の内部マッピングを使用して、ワイヤに書き込む XML 構造を判断します。ランタイムがクラスを認識し、それを XML スキーマ構造にマッピングできる場合は、データを書き出して xsi:type
属性を挿入し、要素に含まれるデータの型を特定します。
ランタイムが Java オブジェクトを既知の XML スキーマ構造にマップできない場合、マーシャリング例外が出力されます。「ランタイムマーシャラーへのクラスの追加」 で説明されている @XmlSeeAlso
アノテーションを使用して、ランタイムのマッピングに型を追加できます。