先週は,JAXBを用いてXMLのスキーマからJavaのクラス生成ができることを紹介しました。そして,生成したクラスを使用してXMLドキュメントからJavaのオブジェクトを生成させました。
XMLのスキーマとJavaのクラスを対応させることをバインディング,XMLドキュメントからJavaのオブジェクトを生成させることをアンマーシャリングということも紹介しました。
今週はアンマーシャリングの逆,マーシャリングを行ってみます。つまり,JavaオブジェクトからXMLドキュメントを生成します。
先週使用した,複数の名前を表すスキーマを今週も使用しましょう。XML Schemaで表したスキーマを次に示します。
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <xs:schema version="1.0" targetNamespace="http://xml.javainthebox.net" xmlns:tns="http://xml.javainthebox.net" xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xs:element name="persons"> <xs:complexType> <xs:sequence> <xs:element ref="tns:person" minOccurs="0" maxOccurs="unbounded"/> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="person"> <xs:complexType> <xs:attribute name="name" type="xs:string"/> <xs:attribute name="age" type="xs:int"/> <xs:attribute name="sex" type="tns:sex"/> </xs:complexType> </xs:element> <xs:simpleType name="sex"> <xs:restriction base="xs:string"> <xs:enumeration value="MALE"/> <xs:enumeration value="FEMALE"/> </xs:restriction> </xs:simpleType> </xs:schema>
スキーマの詳細な解説は行いませんが,何を表しているのかだけ簡単に説明しましょう。
スキーマが四つのパートに別れていることは,すぐにわかるはずです。1番目のバートがスキーマの定義,次がルートタグであるpersonsタグの定義です。personsタグにはpersonタグが複数含まれています。
3番目のパートが,personタグの定義です。personタグにはname,age,sexの三つのアトリビュートが存在します。
最後のパートがsexのアトリビュートに使用できる型の定義です。sexは性別なので,MALEかFEMALEのどちらかの値をとります。
まず,このスキーマからJavaのクラスをxjcコマンドを使って,作成します。
C:\jaxb>xjc persons.xsd parsing a schema... compiling a schema... net\javainthebox\xml\ObjectFactory.java net\javainthebox\xml\Person.java net\javainthebox\xml\Persons.java net\javainthebox\xml\Sex.java net\javainthebox\xml\package-info.java
ファクトリクラスのObjectFactoryクラスとパッケージの定義を行うpackage-info.java以外はすべてスキーマで定義された型に対応しています。
ここまでが,先週のおさらいです。
今週は,これらのクラスを利用してXMLドキュメントを生成していきましょう。
先週紹介したように,XMLドキュメントからJavaのオブジェクトを生成するアンマーシャリングにはjavax.xml.bind.Unmarshallerインタフェースを使用します。
これと同じように,JavaオブジェクトからXMLドキュメントを生成するマーシャリングにはjavax.xml.bind.Marshallerインタフェースを使用します。
Marshallerはインタフェースなので,オブジェクトを得るにはファクトリが必要です。Unmarshallerインタフェースの場合と同じく,このファクトリクラスはjavax.xml.bind.JAXBContextクラスになります。
サンプルのソース | MarshallerSample1.java |
---|
このサンプルはpersons.xsdで定義されたXMLドキュメントを読み込み,Personsオブジェクトを生成します。
public class MarshallerSample1 { public MarshallerSample1() { try { // 1. JAXBContextオブジェクトの生成 // 引数はパッケージもしくはクラス JAXBContext context = JAXBContext.newInstance("net.javainthebox.xml"); // 2. Marsallerオブジェクトの取得 Marshaller marshaller = context.createMarshaller(); // 3. マーシャリングするオブジェクトを準備 Persons persons = createPersons(); // 4. マーシャリング出力先 // 出力にはストリームを使用 FileOutputStream stream = new FileOutputStream("artists2.xml"); // 5. マーシャリング marshaller.marshal(persons, stream); } catch (FileNotFoundException ex) { // 例外処理 System.err.println("artists2.xml がオープンできません"); } catch (JAXBException ex) { // 例外処理 System.err.println("マーシャリングに失敗しました"); } }
JAXBContextオブジェクトの生成には,先週も紹介したようにJAXBContextクラスのnewInstanceメソッドを使用します。
青字で示した部分がMarshallerオブジェクトを生成している部分です。Unmarshallerオブジェクトの場合はcreateUnmarshallerメソッド,Marshallerオブジェクトの場合はcreateMarshallerメソッドを使用します。
マーシャリングには,赤字で示したように,Marshallerインタフェースのmarshalメソッドをコールします。第1引数がマーシャリングするオブジェクト,第2引数がマーシャリングする出力先を示します。
ここでは,ストリームを使用しましたが,アンマーシャリングと同様,多用な出力先を選べます。
- ストリーム/ライター
- XSLTのリザルト
- DOMのノード
- SAXのコンテントハンドラー
- StAXのXMLStreamWriter/XMLEventWriter
マーシャリングの対象となるオブジェクトを生成しているのがcreatePersonsメソッドです。
private Persons createPersons() { Persons persons = new Persons(); Person person = new Person(); person.setName("Paul McCartney"); person.setAge(66); person.setSex(Sex.MALE); persons.getPerson().add(person); person = new Person(); person.setName("Mick Jagger"); person.setAge(65); person.setSex(Sex.MALE); persons.getPerson().add(person); person = new Person(); person.setName("Mary Hopkins"); person.setAge(58); person.setSex(Sex.FEMALE); persons.getPerson().add(person); return persons; }
xjcで生成したPersonsクラス,Personクラスはごくごく普通のクラスです。newを使用して普通に生成し,セッターでフィールドに値をセットしていくだけです。
ソースができたので,コンパイルして実行してみましょう。xjcで生成されたクラスをコンパイルすることを忘れないでください。
正しく動作していれば,artists2.xmlファイルが生成できているはずです。
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><persons xmlns="http://xml.javainthebox.net"><person sex="MALE" age="66" name="Paul McCartney"/><person sex="MALE" age="65" name="Mick Jagger"/><person sex="FEMALE" age="58" name="Mary Hopkins"/></persons>
整形されていないのでちょっと見にくいですが,意図したとおりのXMLファイルが生成されました。