これまで、Java ⇄ JSON みたいな話はしてきた。
このご時世、JSON 大流行りなので、大抵はこれで方が付くんだが、もちろん情報交換のフォーマットとして今でも XML フォーマットは使われている。
ここら辺は「さすが Java」という感じなのだが、Java ネイティブ型 ⇄ XML の変換を取り決めている仕様が存在する。
それが Java Architecture for XML Binding というやつで、JAXB などと呼称されている。
読み方は「ジャックスビー」と思い込んいたが、正式には「ジェイエックスビー」らしいです。
必要性は低くなってきているが、無視はできない
ところで、正直言わせてもらえれば、JAXB の話をするのはあまり気乗りがしていない。
というのは、これまで、この仕様を使わなくてもなんとかなってきたから。
XML を解析するだけであれば、
・jdom(2) を使って解析→コレクション(list や map)を用いて手動で適宜後処理
という手法でも実務上あまり困らないと思う。
これはワイに限ったことではなく、JAXB が Java の正式仕様から外されたり復活したりしている理由は背景にこういった状況があるからだろう。
時代は良くも悪くも JSON 形式なのだ。
ただ、少々汚い形式の XML 文書を Java のオブジェクトとしてプログラム内に取り込んで自由自在に扱うというのは「映え」はする。
なんか釈然としないが、気を取り直して・・・。
準備
マッピングすべきクラスのフィールド変数が基本データ型だけで構成されていればそんなに難しいことはないんだが、配列や list が含まれていると難易度が上がる。
印象としては xml では、要素のまとまりなどは配列的に使われていることが多いと思うが、Java などではこれを list として取り扱いたいということが多いと思う。
配列⇄List の相互変換
Java では、配列と List を相互変換できる。
・配列(Array)→ List のときは Arrays.asLIST
・List → 配列(Array)のときは toArray
を使うのが原則。
List<String> items (= [item1, item2, item3]) があったとき、これを配列 String[] array にしたければ
String[] array = items.toArray(new String[items.size()]);
とする。
逆に array を items に戻したければ
List<String> items = Arrays.asList(array);
とする。
ただし、以下のサンプルコードが示すようにこの小技はあまり使う必要がないかも。
サンプルコード
えいやっと書いてしまった。
Parent.java
public class Parent {
private int id;
private String name;
private List<Child> children;
(以下、セッターゲッター)
せっかく配列や List の話もしたので、Child.java も設定。
public class Child {
private String name;
(以下、セッターゲッター)
この状態でオブジェクトに適当な値を設定。
JAXB.marshal(parent, System.out);
などとすると標準出力に以下のような xml 文書を吐き出してくれる。
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<parent>
<id>1</id>
<name>アグネスタキオン</name>
<children>
<name>ダイワスカーレット</name>
</children>
<children>
<name>ディープスカイ</name>
</children>
</parent>
逆に XML→ Java オブジェクトにしたければ、
JAXB.unmarshal(new StringReader(xml), Parent.class);
などとすればいい。
食わず嫌いでした
実際に手を動かすと意外に使いやすい。
ジャクソンの場合、手を入れる必要がある箇所でも marshal/unmarshal で済んでしまう。
これは食わず嫌いだったかな。
参考記事
https://qiita.com/opengl-8080/items/f7112240c72d61d4cdf4

