今週は,今までとは逆にJavaのクラスからXMLのスキーマを生成することを考えてみます。とはいうものの,Javaのソースだけではちょっと難しいのです。
たとえば,次のJavaのクラスをXMLに変換することを考えてみましょう。
public class Name { String first; String last; .... }
今まで,スキーマからJavaのクラスを生成していた経験から,ルートタグがクラス名に相当することは分かります。では,フィールドは?
<name first="Yuichi" last="Sakuraba" />
このように属性として表すのでしょうか,もしくは次のようにタグとして表すのでしょうか。
<name> <first>Yuichi</first> <last>Sakuraba</last> </name>
答えは,どちらでもかまわないです。
図1 JavaとXMLが表せる範囲 |
---|
より正確に言うならば,Javaのソースだけでは,フィールドをどのようにXMLに対応づけさせるかを指定できない,ということです。
Javaはオブジェクトをベースとしたオブジェクトモデルによって表記をおこないます。それに対し,XMLはツリー構造をベースとした文章モデルによって表記を行ないます。この2つのモデルでは表せる範囲が異なるため,変換ができない部分が残ります。
このように表せる範囲が異なるために発生する不整合をインピーダンスミスマッチといいます(図1)。
インピーダンスミスマッチを解消させるためには,Javaのソースコード以外の手段を使用せざるをえません。
そこで登場するのがアノテーションです。
たとえば,フィールドがXMLドキュメントに変換したときに属性になる場合@XmlAttributeで修飾し,タグになる場合@XmlElementで修飾するようにしてみましょう。
public class Name { @XmlAttribute String first; @XmlAttribute String last; .... }
このように@XmlAttributeで修飾されていれば,XMLドキュメントは次のようになると分かります。
<name first="Yuichi" last="Sakuraba" />
図2 アノテーションで表す範囲 |
---|
つまり,Javaでは表現できない領域をアノテーションを用いることでカバーし,インピーダンスミスマッチを解消しているのです(図2)。
ここで,xjcで生成したJavaのクラスを思いだしてください。今まで無視していましたが,生成したクラスにはアノテーションが付加されています。このアノテーションによって,Javaとスキーマの相互変換が可能になるのです。
それでは,JAXBが使用するアノテーションを紹介していきましょう。
JAXBで使用するアノテーションはjavax.xml.bin.annotationパッケージで定義されており,全部で29種類あります。
以下,主なアノテーションを用途ごとに示します。
クラスを修飾するアノテーション
クラスに使用できるAnnoationは表1に示した4種類です。
アノテーション名 | 説明/デフォルト値 |
---|---|
@XmlType | クラスをスキーマの型に対応づける |
@XmlType( name="##default", propOrder={""}, namespace="##default", factoryClass=DEFAULT.class, factoryMethod="" ) |
|
@XmlRootElement | クラスをスキーマの宣言に対応づける |
@XmlRootElement( name="##default", namespace="##default" ) |
|
@XmlAccessorType | フィールド,プロパティの対応を決定する |
@XmlAccesorType( namespace="http://www.w3.org/2001/XMLSchema", type=DEFAULT.class ) |
|
@XmlAccessorOrder | フィールド,プロパティの対応順序を決める |
なし |