JAXBを使ってxmlファイルを出力する[Java]
JAXBってなに
Java Achitecture for XML Bindingの略.
XMLとJava Objectを相互変換するためのAPIのことです.
イメージ図としてはこんな感じ.
Marshalとは「整列化する」といった意味です.
JavaオブジェクトをXML文字列へ整列化します.
Unmarshalはその逆で「非整列化する」という意味で,
XMLの文字列として整列化されたものをJavaオブジェクトに戻します.
主要インタフェース
インタフェース名 | 説明 |
---|---|
JAXBContext | JAXB APIへのエントリポイントの提供 |
Marshaller | JavaオブジェクトをXMLデータに変換 |
Unmarshaller | XMLデータをJavaオブジェクトに変換 |
今回はMarshal処理を行いたいので,Unmarshallerの説明を割愛します.
JAXBContextインタフェース
// JAXBContextインスタンスの生成 JAXBContext context = null; try { context = JAXBContext.newInstance("com.acme.foo" ); } catch (JAXBException e) { throw e; }
newInstanceメソッドを利用して,JAXBContextの新しいインスタンスを取得します.
newInstanceメソッドの引数はコンテキストパスやクラスを指定したりします.
JAXBContext (Java Platform SE 6)
Marshallerインタフェース
// JAXBContextインスタンスの生成 JAXBContext context = null; try { context = JAXBContext.newInstance("com.acme.foo" ); } catch (JAXBException e) { throw e; } // Marshallerインスタンスの生成 Marshaller marshaller = context.createMarshaller(); // Marshallerのプロパティを設定 // XML出力エンコーディングの指定 marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8"); // XMLデータを改行とインデントを使用して書式設定するか否か marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, new Boolean(true)); // Javaオブジェクト→XML変換処理 try (OutputStream os = new FileOutputStream("item.xml")) { // Javaオブジェクト→XML marshaller.marshal(obj, outputStream); } catch (JAXBException | IOException e) { throw e; }
Marshallerインスタンス生成とプロパティ設定
JAXBContextのcreateMarshallerメソッドを使用して,
MarShallerインスタンスを生成します.
XMLデータにプロパティを設定することができます.
このサンプルプログラムではUTF-8出力と改行・インデントの指定の設定をしています.
プロパティ名 | 説明 |
---|---|
JAXB_ENCODING | 整列化されたXMLデータの出力エンコーディングを指定する |
JAXB_FORMATTED_OUTPUT | 整列化されたXMLデータを改行とインデントを使用して書式設定するかどうかを指定する |
他にもプロパティが存在します.詳細は以下のサイトを参考に.
Marshaller (Java Platform SE 6)
Marshal処理
marshalメソッドでJava ObjectからXMLに変換します.
第1引数には変換元のJava Objectを指定して,第2引数にはXML変換後の出力先を指定します.
marshalメソッド内ではクローズを行わないため,自分でクローズする必要があります.
ここではtry-with-resourcesを使ってます.
実際に自分で作ってみた
JAXBTestProgramクラス
Java Object を XMLデータに出力する動作確認クラスです.
import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.util.ArrayList; import java.util.List; import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBException; import javax.xml.bind.Marshaller; /** * Java Object を XMLデータに出力する動作確認クラス */ public class JAXBTestProgram { public static void main(String[] args) throws Exception { // 出力ファイル名の指定 String fileName = "C:/tmp/test.xml"; // テスト用Java Objectのリストを生成 List<JavaTestBean> list = new ArrayList<>(); list.add(new JavaTestBean(1, "aaa")); list.add(new JavaTestBean(2, "bbb")); list.add(new JavaTestBean(3, "ccc")); // Java Objectのリストの保持 ExampleBean exampleBean = new ExampleBean(); exampleBean.setBeanList(list); JAXBContext context = null; try { // JAXBContextインスタンス生成 context = JAXBContext.newInstance(exampleBean.getClass()); } catch (JAXBException e) { throw e; } Marshaller marshaller = null; try (OutputStream os = new FileOutputStream(fileName)) { // Marshallerインスタンス生成 marshaller = context.createMarshaller(); // XMLデータのプロパティ設定 // エンコーディングの設定 marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8"); // 改行・インデント指定の設定 marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); // Marshal処理 marshaller.marshal(exampleBean, os); // 出力したのをログで知らせる System.out.println("xml出来たよ(^^)"); } catch (JAXBException | IOException e) { throw e; } } }
JavaTestBeanクラス
サンプルJava Objectクラスです.
import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; /** * サンプルJava Objectクラス */ @XmlRootElement(name = "root") public class JavaTestBean { /** id */ private int id; /** name */ private String name; public JavaTestBean() {} public JavaTestBean(int id, String name) { setId(id); setName(name); } @XmlElement public int getId() { return id; } public void setId(int id) { this.id = id; } @XmlElement public String getName() { return name; } public void setName(String name) { this.name = name; } }
ExampleBeanクラス
サンプルJava Objectクラスのリストを保持するクラスです.
つまりこれはJavaTestBeanの上の階層になります.
package jaxbtest; import java.util.List; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; /** * サンプルJava Objectクラスのリストを保持するクラス */ @XmlRootElement(name = "root") public class ExampleBean { /** 保持するリスト */ private List<JavaTestBean> beanList; @XmlElement(name = "record") public List<JavaTestBean> getBeanList() { return beanList; } public void setBeanList(List<JavaTestBean> beanList) { this.beanList = beanList; } }
アノテーションを使って調整しています.
XMLデータのルート要素名を@XmlRootElement
で指定します.
@XmlElement
をGetterかSetterメソッドにつけてタグ名を指定します.
属性名を指定したい場合は@XmlAttribute
を使います.
出力結果
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <root> <record> <id>1</id> <name>aaa</name> </record> <record> <id>2</id> <name>bbb</name> </record> <record> <id>3</id> <name>ccc</name> </record> </root>
アノテーションを駆使すれば求めている出力形式のxmlデータが出せそう.
終わりに
Eclipseだとコメントアウトの所でMarshallerって書くとスペルミスだよの~波線って出る.
Marshalerって書いたら波線がなくなったけど,MarshalerでもMarshallerでも同じ意味.
APIではMarshallerって書いてあるから,別にスペルミスの~波線出なくていいよ頼むよEclipse.
Eclipse重すぎてIntelliJが恋しい.やっぱりJetBrainsで快適プヨヨグラミングがしたいなあ~.
学生の頃は無料サブスクリプションで使い放題だったけど,社会人だとお金かかるのが世知辛い.
参考記事
Java Architecture for XML Binding - Wikipedia
XMLDBとJavaAPI、JAXB2.0を活用したWebアプリケーション開発(APIチュートリアル編) (1/3):CodeZine(コードジン)
JAXB (Java Platform SE 6)
Java XML JAXBメモ(Hishidama's XML JAXB Memo)
JAXB使い方メモ - Qiita