note


JAXBとSimpleXML

XMLとJavaの架け橋として、Java 6.0からJAXBが正式に追加された。XMLからJavaオブジェクトを作成したり、Java ObjectからXMLを生成したりとJAXBはわりと便利で、私も2008年ごろにXMLベースのイベント記述言語と実行ランタイムを実装するのに使ってました。

今回androidでXMLを触る機会があったのでJAXBを久しぶりに試してみようかな、と思ったのですが、Androidではサポートしてないため、代替案として
SimpleXMLを触ってみました。サンプルが充実してるので、簡単です。SimleXMLではxsdからJavaクラスを生成みたいな機能はないみたいなので、ずぼらな私はまずJAXBでxsdからJavaクラスを生成させ、それをSimpleXMLにあうように変更しました。かなり簡単で、例えばあるクラス内にStringの変数があったとしたら

(JAXB)
@XmlAttribute(required = true)
protected String id;

(SimpleXML)
@Attribute (required=true)
protected String id;


ってな感じ。required=trueは、その要素を必ず持つ必要があるようにスキーマが定義されていれば、JAXBと同じように生成します。
また、子要素が複数あらわれるようなタグに関して、JAXBではListを使った変数が生成されますが、それも、


(JAXB)
protected List testValues;

(SimpleXML)
@ElementList (inline=true,required=false)
protected List testValues;


ってな感じです。このinline=true というのが、あるとなしだとSimpleXMLがJavaオブジェクトから生成するXMLがかなり変わって、
inline=false の場合、


<data>
<test class="java.util.ArrayList">
<test id=“hoge” value=“hoge”/>
<test id=“”hoge2 value=“”hoge2/>
</test>
</data>


このように、
<test class="java.util.ArrayList”></test>
とくっついてきちゃいます。
inline=trueにすると、


<data>
<test id=“hoge” value=“hoge”/>
<test id=“”hoge2 value=“”hoge2/>
</data>


と、(私が)意図したとおりのスキーマに従ったXMLが生成されます。
SimpleXMLでJavaオブジェクトからXMLを生成する(JAXBでいうmarshaller)のは、例えばDataクラスが定義されてるとして、


public String dataToXml(Data data){
StringWriter writer= new StringWriter();
Serializer serializer = new Persister();
try {
serializer.write(data, writer);
} catch (Exception e) {
e.printStackTrace();
}
return writer.toString();
}


みたいな感じで、簡単。
JAXBでXMLから生成したJavaクラスからSimpleXML用のJavaクラスに変更Scriptもわりと簡単に書けそうなので、あってもよさそう。