mb_language("uni"); mb_internal_encoding("utf-8"); mb_http_input("auto"); mb_http_output("utf-8"); ?>
samples-vol1.jar はこちらからダウンロードできます
リレーショナルデータベース(以降、RDB)とXMLデータベース(以降、XML DB)とでは、プログラミングスタイルに多少の違いはあるにせよ、難易度にはそれほど違いはない。別稿「徹底比較!RDB vs XML DB」で検討したように、スキーマ変更に柔軟に対応できるなど、XML DBの方が優れている点もある。もし、XML DBに取っつきにくさを感じてしまうことがあるとしたら、RDBに比べて具体的な活用事例に触れる機会が少ないことが原因の1つかもしれない。
そこで本稿では、XML DBを使った実際のアプリケーション事例を紹介したい。紹介するのはXML2CSV、データベースに格納されたXML文書をCSV(Commma Separated Values:カンマ区切り)形式に変換するツールだ。XML2CSVを使うと、CSVを入力とするようなプロダクトとXML DB上のデータとを連携させることができる。事例から、XML DB活用方法のイメージの幅を広げてみてほしい。
XML2CSVは、2つの部分から構成される。
・変換定義情報作成ツールConfig_XML2CSV
・Xml2CsvCommon.jarライブラリ
XMLからCSVへのデータ変換を行うにはまず、XMLの半構造データをCSVのフラットなデータにどうやって置き換えるか、という変換方法の定義をしなくてはならない。変換方法はXQueryを使って書くわけだが、定義情報を元にXQueryを自動生成してくれるGUIツールがConfig_XML2CSVだ。
▲変換定義情報作成ツールConfig_XML2CSV
そして、変換定義情報を元に、実際に変換を実行するためのライブラリがXml2CsvCommon.jarだ。XML2CSVでは、ツールから直接CSVファイルが出力される訳ではなく、CSVファイルを出力するプログラムを書くためのライブラリが提供される。変換されたCSVを読み込ませるアプリケーションに応じて、自由にカスタマイズして使えばよい。
XML2CSVは以下のサイトからダウンロードすることができる。
Confg_XML2CSVの機能上のポイントを解説する。
●マルチオカレンス指定とINDEX指定
XMLからCSVへの変換で考えなければいけないのは、繰り返しのあるデータにどう対応するかということだ。XMLからCSVへの変換は、ツリー構造からフラット構造へのデータ変換となる。
▲ツリー構造からフラット構造への変換
しかし、次のように、同じ要素が複数回出現する可能性のあるXMLの場合、単純にデータをCSVの1レコードに変換できない。
▲繰り返し要素のあるXMLデータ
XML2CSVではこうしたXMLデータの変換に、「マルチオカレンス指定」「INDEX指定」の2つの方法を用意している。マルチオカレンス指定は、あるノードの下に複数の単位データ(CSVの1行に相当)が並置されているような構造をもつXMLを、CSVに変換したいときに利用する。
▲マルチオカレンス指定
一方、INDEX指定は、単位データの中に同じ要素が複数登場するような場合に、それをCSVの1行に展開したいときに使う。複数登場する要素の順番(INDEX)を指定することで、同じ要素を1行の別々の列に割り振ることができる。
▲INDEX指定
XMLは半構造データであり、CSVの1行に相当するデータ単位の保持のしかたについては自由度が大きい。XMLによって、様々な構成が考えられる。変換したいXMLがどんな構成かに応じて、上記2つの方法のうち適したものを選んでゆけばよい。
基準ノードとXQueryの自動生成
XMLの構造がある程度複雑になると、変換のためのXQueryも複雑になってくる。XQueryを自動的に生成してくれるのが、Config_XML2CSVの最大のポイントだ。XQuery生成にあたり、Config_XML2CSVは「基準ノード」という考え方を導入する。基準ノードとは、XQuery内でデータ要素を指定する際の基準となるノードのことだ。生成されたXQueryで指定されるデータ要素は、すべて基準ノードからの相対パスで表される。Config_XML2CSVから生成されるXQueryは以下のようになる。変数「$rec」が、基準ノードを表している。
for $rec in /ND/注文データ/注文 for $f3 in $rec/商品情報 for $f6 in $rec/購入先情報 return <result> <注文番号>{$rec/注文番号/text()}</注文番号> <発注個数>{$rec/発注個数/text()}</発注個数> <商品名>{$f3/商品名/text()}</商品名> <単価>{$f3/単価/text()}</単価> <購入先名>{$f6/購入先名/text()}</購入先名> <購入先連絡先>{$f6/購入先連絡先/text()}</購入先連絡先> </result> |
XMLからCSVへの変換方法の定義は、Config_XML2CSVのGUI画面を通して行う。変換定義情報は、以下のようなXMLで表される。この情報を元に、XML2CSVはXQueryを自動生成する。
<xml2csv> <config id="order"> ...中略... <document>注文データ</document> <recordtag>/ND/注文データ/注文</recordtag> <csvfile></csvfile> <multioccurrence></multioccurrence> <csvtypeflag>false</csvtypeflag> <memo></memo> <field> <xmltag>./注文番号</xmltag> <index></index> <csvfield>注文番号</csvfield> <csvtype></csvtype> </field> <field> <xmltag>./発注個数</xmltag> <index></index> <csvfield>発注個数</csvfield> <csvtype></csvtype> </field> ...中略... </config> </xml2csv> |
この変換定義情報は、Config_XML2CSVの画面からファイルに書き出すことも、XML DB上に格納しておくこともできる。
GUIツールによって変換定義情報を作成したら、それを元にXMLからCSVへの変換を行うことができる。Xml2CsvCommon.jarライブラリを使って、どうやって変換をプログラミングするかを説明しよう。
変換を実行するプログラムは、次のようになる。Config_XML2CSVを使って作成しXML DBに保存した変換定義情報を使って、CSVを標準出力に表示させるプログラムだ。サンプルではcom.neocore.httpclient.NeoConnectionクラスを使ってDBへ接続しているが、接続プーリングなどの本格的な機能を利用できるcom.neocore.httpclient.SessionManagedNeoConnectionクラスもある。
package to.msn.wings.xml2csv; import java.io.BufferedReader; import java.io.ByteArrayinputStream; import java.io.inputStreamReader; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import mki.xml2csv.access.Xml2CsvNeoCoreAccess; import mki.xml2csv.access.Xml2CsvSax2; import mki.xml2csv.model.Xml2CsvConfigModel; import com.neocore.httpclient.NeoConnection; public class Xml2CsvSample { public static void main(String[] args) { try { // Xprioriへの接続開始 NeoConnection neo = new NeoConnection("localhost", 7700); String sessionId = neo.login("Administrator", "admin"); Xml2CsvNeoCoreAccess neoaccess = new Xml2CsvNeoCoreAccess( neo, sessionId); // Xprioriから変換定義情報「order」を読込 Xml2CsvConfigModel config = neoaccess.getConfigModel( "order", "UTF-8"); // 変換定義情報からXQueryを生成 String query = config.getQuery(); // CSVデータの元となる、フラットなXMLデータを取得 String result = neo.queryXML(sessionId, query); // CSVへの変換 SAXParserFactory spfactory = SAXParserFactory.newInstance(); SAXParser parser = spfactory.newSAXParser(); Xml2CsvSax2 handler = new Xml2CsvSax2(); handler.config = config; parser.parse( new ByteArrayinputStream(result.getBytes("UTF-8")), handler); // CSVを表示 BufferedReader reader = new BufferedReader(new inputStreamReader( handler.istream)); while (reader.ready()) { System.out.println(reader.readLine()); } } catch (Exception e) { e.printStackTrace(); } } } |
サンプルプログラムは、以下のようなXMLデータとCSVデータとの変換を実行するものとする。
<注文データ> <注文> <注文番号>ABCD-123-Z</注文番号> <発注個数>12</発注個数> <商品情報> <商品名>電子回路A</商品名> <単価>12340</単価> </商品情報> <購入先情報> <購入先名>佐藤電機</購入先名> <購入先連絡先>012-3456-7890</購入先連絡先> </購入先情報> </注文> ...中略... </注文データ> |
ABCD-123-Z, 12, 電子回路A, 12340, 佐藤電機, 012-3456-7890 ...中略... |
プログラムのポイントは、次の通りだ。まず、Xml2CsvNeoCoreAcccessクラスを使って、XML DBとの接続を確立する。次に、そこからXml2CsvConfigModelオブジェクトを取得する。Xml2CsvConfigModelは変換定義情報を表すクラスであり、自動生成されたXQueryもこのクラスから取得できる。生成されたXQueryを実行するのは、XML2CSVを通さず、通常のXpriori APIを利用する。XQueryを通して取得されたデータは、まだ単なるフラットなXMLデータである。最終的にCSVデータへの変換を実行するには、Xml2CsvSax2クラスを用いる。
ライブラリの使い方を簡単にまとめると、4つのステップとなる。
1. Xml2CsvNeoCoreAcccessクラスを使ってXML DBにアクセス
2. Xml2CsvConfigModelオブジェクトを取得
3. 生成されたXQueryを使ってデータを取得
4. Xml2CsvSax2クラスを使って、結果をCSVに変換
サンプルプログラムの実行には、以下のコマンドを入力する。
> SET CLASSPATH=".;C:\Xpriori\API\Java\lib\xmlclient.jar;C:\xml2csv\Xml2CsvCommon.jar" > javac to\msn\wings\xml2csv\Xml2CsvSample.java > java to.msn.wings.xml2csv.Xml2CsvSample ...中略... ABCD-123-Z, 12, 電子回路A, 12340, 佐藤電機, 012-3456-7890 |
以上、XML DBを使ったアプリケーション事例としてXML2CSVを紹介した。XML DBプログラミングそのものには踏み込まず、XML2CSVが機能面でどういったものを提供するのかを説明した。ここでは、とりあえずXML DBの使い方にはこんなものもあるのか、というイメージをつかんでいただけたらそれでよい。
次回は、XML2CSVのソースコードを実際に読み、実践的なXML DBプログラミングのポイントをおさえていきたい。
▲このページのTOPへ