36.3. バインドされていない属性の使用
概要
XML スキーマには、複合型定義内の任意の属性のプレースホルダーを残すことができるメカニズムがあります。このメカニズムを使用すると、任意の属性を持つことができる複合型を定義できます。たとえば、3 つの属性を指定せずに、要素 <robot name="epsilon" />、<robot age="10000" />、または <robot type="weevil" /> を定義するタイプを作成できます。これは、データに柔軟性が必要な場合に特に役立ちます。
XML スキーマでの定義
宣言されていない属性は、anyAttribute
要素を使用して XML スキーマで定義されます。属性要素を使用できる場所であればどこでも使用できます。例36.7「宣言されていない属性を持つ複合型」に示されているように、anyAttribute
要素には属性がありません。
例36.7 宣言されていない属性を持つ複合型
<complexType name="arbitter">
<sequence>
<element name="name" type="xsd:string" />
<element name="rate" type="xsd:float" />
</sequence>
<anyAttribute />
</complexType>
定義された型 arbitter
には 2 つの要素があり、任意の型の属性を 1 つ設定できます。例36.8「ワイルドカード属性で定義された要素の例」 に記載されている 3 つの要素は、すべて複合型 arbitter
から生成できます。
例36.8 ワイルドカード属性で定義された要素の例
<officer rank="12"><name>...</name><rate>...</rate></officer> <lawyer type="divorce"><name>...</name><rate>...</rate></lawyer> <judge><name>...</name><rate>...</rate></judge>
Java へのマッピング
anyAttribute
要素を含む複合型が Java にマップされると、コードジェネレーターは、生成されたクラスに otherAttributes
というメンバーを追加します。otherAttributes
は java.util.Map<QName, String>
タイプであり、マップのライブインスタンスを返すゲッターメソッドを持ちます。ゲッターから返されたマップはライブであるため、マップへの変更は自動的に適用されます。例36.9「宣言されていない属性を持つ複合型のクラス」 は、例36.7「宣言されていない属性を持つ複合型」 で定義された複合型に対して生成されたクラスを示します。
例36.9 宣言されていない属性を持つ複合型のクラス
public class Arbitter { @XmlElement(required = true) protected String name; protected float rate; @XmlAnyAttribute private Map<QName, String> otherAttributes = new HashMap<QName, String>(); public String getName() { return name; } public void setName(String value) { this.name = value; } public float getRate() { return rate; } public void setRate(float value) { this.rate = value; } public Map<QName, String> getOtherAttributes() { return otherAttributes; } }
宣言されていない属性の操作
生成されたクラスの otherAttributes
メンバーには、Map
オブジェクトが設定される必要があります。マップは QNames
を使用してキーが付けられます。マップを取得すると、オブジェクトに設定されている任意の属性にアクセスして、オブジェクトに新しい属性を設定できます。
例36.10「宣言されていない属性の操作」 は、宣言されていない属性を操作するためのサンプルコードを示しています。
例36.10 宣言されていない属性の操作
Arbitter judge = new Arbitter(); Map<QName, String> otherAtts = judge.getOtherAttributes(); QName at1 = new QName("test.apache.org", "house"); QName at2 = new QName("test.apache.org", "veteran"); otherAtts.put(at1, "Cape"); otherAtts.put(at2, "false"); String vetStatus = otherAtts.get(at2);
例36.10「宣言されていない属性の操作」 のコードは、以下を行います。
宣言されていない属性を含むマップを取得します。
属性を操作する QName を作成します。
属性の値をマップに設定します。
属性の 1 つの値を取得します。