JAXBアノテーション
JAXBの主要クラスの説明に続いてJAXB 2.0から追加されたJAXBアノテーションについて説明します。JAXB 2.0以前は、JAXBを用いたアプリケーションの開発過程の中で、XMLの構造を定義したXMLSchemaファイルを必ず作成する必要があり、敷居がやや高いというデメリットがありました。しかしJAXB 2.0からは、JAXBアノテーションをJavaクラスに定義することで、JavaクラスとXMLの関連付けが容易に可能になり、XMLSchemaファイルの作成も必須ではなくなりました。ここではjavax.xml.bind.annotationパッケージに定義されている32のアノテーションのうち、最も頻繁に使用するであろうアノテーション(XmlRootElement、XmlType、XmlElement、XmlAttribute)について説明します。
JavaクラスとXMLルート要素の関連付け(XmlRootElement)
JavaトップクラスとXMLのルート要素を関連付けるには、@XmlRootElementを使用します。クラス名とXMLのルート要素の名前が異なる場合は、@XmlRootElementのname属性にXMLのルート要素名を指定します。以下に@XmlRootElementを定義したソースを示します。
import javax.xml.bind.annotation.XmlRootElement; // ~省略 @XmlRootElement(name="item") public class Item{
@XmlRootElementで定義したルート要素は、XMLSchemaのxs:element(ルート要素)に対応します。以下に上記Javaソースに対応するXMLSchemaの定義を示します。
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <xs:schema version="1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xs:element name="item" type="item"/> </xs:schema>
要素並び順の定義(XmlType)
XML要素の並び順を定義するには、@XmlTypeを使用します。@XmlTypeはXMLSchemaの「xs:complexType(複合型)」とマッピングします。@XmlTypeは、@XmlRootElem、@XmlAccessorOrder、@XmlAccessorType、@XmlEnumのアノテーションとセットで使用することができます。
以下がXmlRootElementとXmlTypeを使用して要素の並び順を定義したサンプルソースです。
import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlType; // ~省略 @XmlRootElement(name="item") @XmlType(propOrder={ "itemName", "price" }) public class Item { @XmlElement(name="item_name") public String getItemName() { return itemName; } @XmlElement(name="price") public int getPrice() { return price; } }
@XmlTypeで定義する並び順は、XMLSchemaのxs:sequenceに対応します。以下に上記Javaソースに対応するXMLSchemaの定義を示します。
<xs:complexType name="item"> <xs:sequence> <xs:element name="item_name" type="xs:string"/> <xs:element name="price" type="xs:int"/> </xs:sequence>
Javaクラスのインスタンス変数とXML要素の関連付け(XmlElement)
Javaクラスのインスタンス変数とXMLの要素を関連付けるには、@XmlElementを使用します。@XmlTypeはXMLSchemaの「xs:element」とマッピングします。Javaクラスのインスタンス変数名とXMLの要素名が異なる場合には、name属性を使用することによって関連付けることができます。また、インスタンス変数の型によって、マッピングされるXML要素の型も決定されます。例えば、インスタンス変数の型がStringの場合は、xs:string、intの場合はxs:int、java.util.Dateの場合はxs:dateTimeにそれぞれマッピングされます。
import javax.xml.bind.annotation.XmlElement; // ~省略 @XmlElement(name="item_name",nillable=true, required=true) public String getItemName() { return itemName; } // publicのインスタンス変数に定義することもできる @XmlElement(name="pref_name") public String prefName;
@XmlElementの定義は、XMLSchemaのxs:elementに対応しますが、アノテーションの丸カッコ内に属性を定義することによってxs:elementの属性値を明示的に設定することができます。以下の表に@XmlElementの属性とxs:elementの属性の対応、省略時のデフォルト値をまとめました。
| @XmlElementの属性 | xs:elementの属性 | 説明 | 省略時のXMLSchema上の属性デフォルト値 |
| name | name | XML要素名 | Javaクラスのインスタンス変数名 |
| defaultValue | default | 要素のデフォルト値 | null |
| type | type | 要素のデータ型 | Javaクラスのインスタンス変数のクラスにマッピングした型(XMLSchemaのビルトインデータ型、もしくは作成したクラス) |
| namespace | namespace | 要素が属する名前空間名 | 空値 |
| required | minOccurs | 要素の繰り返し回数 | 1 |
以下に上記Javaソースに対応するXMLSchemaの定義を示します。
<xs:element name="item_name" type="xs:string" nillable="true"/> <xs:element name="pref_name" type="xs:string" minOccurs="0"/>
Javaクラスのインスタンス変数とXML属性の関連付け(XmlAttribute)
Javaクラスのインスタンス変数とXMLの属性を関連付けるには、@XmlAttributeを使用します。Javaクラスのインスタンス変数名とXMLの属性名が異なる場合には、name属性を使用することによって関連付けることができます。属性の場合も要素と同じくJavaクラスのインスタンス変数の型によって、マッピングされるXML要素の型が決定されます。
import javax.xml.bind.annotation.XmlAttribute; // ~省略 @XmlAttribute(name="item_code") public String getItemCode() { return itemCode; }
@XmlAttributeの定義は、XMLSchemaのxs:attributeに対応しますが、アノテーションの丸カッコ内に属性を定義することによってxs:attributeの属性値を明示的に設定することができます。以下の表に@XmlAttributeの属性とxs:attributeの属性の対応をまとめました。
| @XmlAttributeの属性 | xs:attributeの属性 | 説明 | 省略時のXMLSchema上の属性デフォルト値 |
| name | name | XML要素名 | Javaクラスのインスタンス変数名 |
| namespace | namespace | 属性が属する名前空間名 | 空値 |
| required | use | 属性を必ず使用するか、任意か | optional |
以下に上記Javaソースに対応するXMLSchemaの定義を示します。
<xs:attribute name="item_code" type="xs:string" use="required"/>
XMLのラッパー要素定義
XMLのラッパー要素とは、XML要素をひとくくりにするために使用される要素です。主に同じ要素が繰り返される場合に、その繰り返し要素をある親要素で囲むような場合に使用されます。Javaクラスの属性にラップされる要素(サンプルではoption)の@XmlElementの記述とセットで@XmlElementWrapper(サンプルで対応する要素はoptions)を指定します。繰り返しの要素は、Javaクラス上では配列やListなどで表現されます。
import javax.xml.bind.annotation.XmlElementWrapper; import javax.xml.bind.annotation.XmlRootElement; // ~省略 @XmlElementWrapper(name="options") @XmlElement(name="option") public List<String> getOptions() { return options; }
@XmlElementWrapperの定義は、XMLSchemaのxs:elementとxs:complexTypeの組み合わせに対応します。以下に上記Javaソースに対応するXMLSchemaの定義を示します。
<xs:element name="options" minOccurs="0"> <xs:complexType> <xs:sequence> <xs:element name="option" type="xs:string" maxOccurs="unbounded" minOccurs="0"/> </xs:sequence> </xs:complexType> </xs:element>
また、上記XMLSchemaのXML要素の例を以下に示します。option要素がoptions要素で囲まれています。
<options> <option>L</option> <option>M</option> </options>
XMLスキーマファイルの出力
JDK 6に標準で付属しているschemagenというツールを使用して、XMLスキーマファイルを出力することができます。なお、スキーマファイルを使用しなくても、サンプルアプリケーションは実行できます。アプリケーション内でXMLバリデーションを実行する場合は、schemagenで生成したファイルを使用すると良いでしょう。
schemagenは以下の方法で実行します。
cd ソースフォルダ schemagen -cp jp\beproud\sample\ecitem\entity\*.java
カレントフォルダにファイルが作成されると、以下のメッセージが出力されます。
注:Writing schema1.xsd
schemagenで出力したXMLSchemaファイルの例については次回、サンプルアプリケーションのクラス定義に基づいて作成されたファイルを掲載します。
