*めんどくさいXML処理 [#n3701983]
XMLファイルの読み書きをみなさんはどうやっているでしょうか? DOMやSAXを利用してプログラムを組んでいる人が殆どだと思いますが、ツリーを辿ったり、イベントのハンドリング処理を書いたり、はっきり言ってめんどくさくないですか? Digester等のJavaオブジェクトとXMLファイルをマッピングするようなフレームワークもありますが、マッピングファイルを書くのが面倒だったり、読み込みしか対応していなかったり、やっぱり不便です。
*XMLBeansとは? [#maa80e60]
XMLBeansはXML文書をJavaオブジェクトへ読み書きするJava/XMLデータバインディングツールです。XMLBeansを利用すると、XML文書の型をXMLスキーマとして定義さえすれば、XML文書をJavaオブジェクトへ読み込んだり、JavaオブジェクトをXML文書へ書き出したりすることが簡単にできます。ここでは、XMLBeans(バージョンは2.0)の使い方を簡潔に解説します。XMLBeansの詳細については、[[Apache XMLBeansのサイト:]]をご覧下さい。
*XML文書 [#hde90a80]
例えば、次のようなXML文書members.xmlがあるとします。
<?xml version="1.0" encoding="utf-8"?>
<members xmlns="http://ultimania.org/members">
<member id="1">
<name>ライト</name>
<organization>警察</organization>
</member>
<member id="2">
<name>ニア</name>
<organization>SPK</organization>
</member>
<member id="3">
<name>メロ</name>
<organization>マフィア</organization>
</member>
</members>
このXML文書の型を定義するXMLスキーマ(W3C XML Schema)members.xsdは次のようになります。
<?xml version='1.0' encoding='utf-8'?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:m="http://ultimania.org/members"
targetNamespace="http://ultimania.org/members"
elementFormDefault="qualified">
<!-- members要素 -->
<xs:element name="members">
<xs:complexType>
<xs:sequence>
<!-- member要素を繰り返しで定義-->
<xs:element minOccurs="0"
maxOccurs="unbounded" ref="m:member" />
</xs:sequence>
</xs:complexType>
</xs:element>
<!-- member要素 -->
<xs:element name="member">
<xs:complexType>
<xs:sequence>
<!-- name要素 -->
<xs:element name="name" type="xs:string" />
<!-- organization要素 -->
<xs:element name="organization" type="xs:string" />
</xs:sequence>
<!-- id属性 -->
<xs:attribute name="id" type="xs:int"/>
</xs:complexType>
</xs:element>
</xs:schema>
XMLスキーマの詳細については、[[簡単なXML Schemaから始めよう:http://www.extd-web.com/blog]]や[[XML Schema Part 0: Primer Second Edition:http://www.lian-game.com/blog]]等をご覧ください。
*使い方 [#e2b56c4b]
XMLBeansを使うと、上記のXMLスキーマにアクセスするJavaクラスを生成することができます。XMLBeansはコマンドラインやAntから利用することができますが、ここではAntから利用してみることにします。Antから利用するには、次のようなbuild.xmlを作成します。
<?xml version="1.0" encoding="utf-8"?>
<project name="XMLBeans 2.0beta1" default="xmlbean" basedir=".">
<!-- XMLBeansのインストールディレクトリを指定 -->
<property name="xmlbeans.home"
value="c:/xmlbeans-2.0.0-beta1" />
<!-- XMLスキーマを指定 -->
<property name="schema" value="members.xsd" />
<!-- 出力するjarファイル名を指定 -->
<property name="dest.jar"
value="beans.jar" />
<path id="xmlbeans.path">
<fileset dir="${xmlbeans.home}/lib" includes="*.jar"/>
</path>
<taskdef name="xmlbean"
classname="org.apache.xmlbeans.impl.tool.XMLBean"
classpathref="xmlbeans.path"
/>
<target name="xmlbean">
<xmlbean schema="${schema}"
destfile="${dest.jar}"
classpathref="xmlbeans.path" />
</target>
</project>
上記のxmlbeans.home、schema、dest.jarは環境に合わせて適当に変更してください。antを実行すると次のようなメッセージと共にbeans.jarファイルが生成されます。
> ant
Buildfile: build.xml
xmlbean:
[xmlbean] Time to build schema type system: 1.512 seconds
[xmlbean] Time to generate code: 0.12 seconds
[xmlbean] Compiling 4 source files to c:\DOCUME~1\OKAMOT~1\LOCALS~1\Temp\xbean64423.d\classes
[xmlbean] Time to compile code: 1.312 seconds
[xmlbean] Building jar: D:\tmp\xmlbeans\beans.jar
BUILD SUCCESSFUL
Total time: 4 seconds
okamototk@violin /cygdrive/d/tmp/xmlbeans
> dir beans.jar
beans.jar
さて、このbeans.jarを使ってXML文書を読み込んでみましょう。members.xmlを読み込むコードは、次のようになります。
import org.ultimania.members.*;
import java.io.*;
public class Hello {
public static void main(String args[]) throws Exception {
MembersDocument membersDoc = MembersDocument.Factory.parse(new File(args[0]));
MembersDocument.Members members = membersDoc.getMembers();
MemberDocument.Member [] member = members.getMemberArray();
for(int i=0;i<member.length;i++){
System.out.println("id="+member[i].getId());
System.out.println("name="+member[i].getName());
System.out.println("organization="+member[i].getOrganization());
}
}
}
XMLBEANS_HOME/lib/xbeans.jar、XMLBEANS_HOME/lib/jsr173_api.jar、先程生成したbeans.jarにクラスパスを通して、ソースをコンパイル、実行すると、次のような結果を得られます。
> java
-classpath "xbeans.jar;XMLBEANS_HOME/lib/xbeans.jar;XMLBEANS_HOME/lib/jsr173_api.jar;."
Hello members.xml
id=1
name=ライト
organization=警察
id=2
name=ニア
organization=SPK
id=3
name=メロ
organization=マフィア
*DTD/RelaxNGの利用 [#w743ded0]
XMLBeansはW3C XMLスキーマにしか対応していません。DTDやRelax NGで記述されたスキーマを扱うには、Trangを利用し、DTDやRelax NGのスキーマをW3C XMLスキーマに変換して利用します。Trangは次のサイトからダウンロードします。
-http://www.thaiopensource.com/relaxng/trang.html
trangは次のように使います。
***DTDをW3C XMLスキーマへ変換 [#qb90b137]
$ java -jar trang.jar foo.dtd foo.xsd
***Relax NGをW3C XMLスキーマへ変換 [#g94e0ce0]
$ java -jar trang.jar foo.rng foo.xsd
trangは拡張子で自動的に判別して、あるXMLスキーマから別のXMLスキーマの形式へ変換します。
*FAQ [#k0d2ab06]
***ネームスペースの宣言を省略するには? [#jce48ee8]
DTDで宣言されたXML文書ではネームスペース宣言が省略されることが多々あります。ネームスペースの宣言を省略するには、次のようにします。
XmlOptions opts = new XmlOptions();
Map map = new HashMap();
map.put("","http://ultimania.org/members");
opt.setLoadSubstituteNamespaces(map);
MembersDocument membersDoc = MembersDocument.Factory.parse(new File(args[0]), opts);
上記のようにすると、上記のサンプルの
<members xmlns="http://ultimania.org/members">
とネームスペースの宣言をしている所を省略し、
<members>
と書くことができます。
*より詳しい情報 [#q7e511c4]
-XMLBeansのより詳しい紹介は、BEAのサイトの記事にあります。
http://edocs.beasys.co.jp/e-docs/workshop/docs81/doc/ja_JP/workshop/guide/xmlbeans/conGettingStartedwithXMLBeans.html?skipReload=
-XMLBeansのAntタスクの使い方は、http://xmlbeans.apache.org/docs/2.0.0/guide/antXmlbean.htmlにあります。
[http://horse.sub.jp/ 競馬予想]