Menu Close
第36章 ワイルドカード型の使用
概要
スキーマ作成者が、要素や属性を定義された型に別途バインディングしたい場合があります。このような場合、XML スキーマはワイルドカードのプレースホルダーを指定するための 3 つのメカニズムを提供します。これらはすべて、XML スキーマ機能を保持する方法で Java にマッピングされます。
36.1. 任意の要素の使用
概要
XML スキーマの any
要素を使用して、複合型の定義にワイルドカードのプレースホルダーを作成します。XML 要素が XML スキーマの any
要素に対してインスタンス化されると、有効な任意の XML 要素として使用できます。any
要素は、インスタンス化した XML 要素のコンテンツまたは名前のいずれにも制限を設けません。
たとえば、例36.1「any 要素で定義された XML スキーマ型」で定義された複合型では、例36.2「any 要素を使用する XML ドキュメント」に示されている XML 要素のいずれかをインスタンス化できます。
例36.1 any 要素で定義された XML スキーマ型
<element name="FlyBoy"> <complexType> <sequence> <any /> <element name="rank" type="xsd:int" /> </sequence> </complexType> </element>
例36.2 any 要素を使用する XML ドキュメント
<FlyBoy> <learJet>CL-215</learJet> <rank>2</rank> </element> <FlyBoy> <viper>Mark II</viper> <rank>1</rank> </element>
XML スキーマの any
要素は、Java Object
オブジェクトまたは Java org.w3c.dom.Element
オブジェクトのいずれかにマッピングされます。
XML スキーマでの指定
any
要素は、sequence 複合型や choice 複合型を定義するときに使用できます。多くの場合、any
要素は空の要素です。ただし、annotation
要素を子として取ることができます。
表36.1「XML スキーマの any 要素の属性」で any
要素の属性を説明します。
表36.1 XML スキーマの any 要素の属性
属性 | 説明 |
---|---|
| XML ドキュメントで要素をインスタンス化するために使用できる要素の namespace を指定します。有効な値を以下に示します。
|
|
要素のインスタンスを親要素に表示できる最大回数を指定します。デフォルト値は |
|
要素のインスタンスを親要素に表示できる最少回数を指定します。デフォルト値は |
| 任意の要素のインスタンス化に使用される要素の検証方法を指定します。有効な値を以下に示します。
|
例36.3「any 要素で定義された複合型」に、any
要素で定義された複合型を示します。
例36.3 any 要素で定義された複合型
<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「any 要素を使用する Java クラス」に、例36.3「any 要素で定義された複合型」で定義された複合型がどのように Java クラスにマッピングされるかを示します。
例36.4 any 要素を使用する 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
アノテーションを使用して、ランタイムのマッピングに型を追加できます。