めんどくさい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>

と書くことができます。

より詳しい情報

競馬予想


トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2010-10-19 (火) 21:21:36 (5369d)