めんどくさいXML処理 †XMLファイルの読み書きをみなさんはどうやっているでしょうか? DOMやSAXを利用してプログラムを組んでいる人が殆どだと思いますが、ツリーを辿ったり、イベントのハンドリング処理を書いたり、はっきり言ってめんどくさくないですか? Digester等のJavaオブジェクトとXMLファイルをマッピングするようなフレームワークもありますが、マッピングファイルを書くのが面倒だったり、読み込みしか対応していなかったり、やっぱり不便です。 XMLBeansとは? †XMLBeansはXML文書をJavaオブジェクトへ読み書きするJava/XMLデータバインディングツールです。XMLBeansを利用すると、XML文書の型をXMLスキーマとして定義さえすれば、XML文書をJavaオブジェクトへ読み込んだり、JavaオブジェクトをXML文書へ書き出したりすることが簡単にできます。ここでは、XMLBeans(バージョンは2.0)の使い方を簡潔に解説します。XMLBeansの詳細については、Apache XMLBeansのサイト:?をご覧下さい。 XML文書 †例えば、次のような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から始めようやXML Schema Part 0: Primer Second Edition等をご覧ください。 使い方 †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の利用 †XMLBeansはW3C XMLスキーマにしか対応していません。DTDやRelax NGで記述されたスキーマを扱うには、Trangを利用し、DTDやRelax NGのスキーマをW3C XMLスキーマに変換して利用します。Trangは次のサイトからダウンロードします。
DTDをW3C XMLスキーマへ変換 †$ java -jar trang.jar foo.dtd foo.xsd Relax NGをW3C XMLスキーマへ変換 †$ java -jar trang.jar foo.rng foo.xsd trangは拡張子で自動的に判別して、あるXMLスキーマから別のXMLスキーマの形式へ変換します。 FAQ †ネームスペースの宣言を省略するには? †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> と書くことができます。 より詳しい情報 †
|