XMLDB.jp

XMLDB開発支援
HOME  >  XMLDB開発支援  >  XML2CSVで学ぶ実践的なXprioriプログラミング 第3回

XML2CSVで学ぶ実践的なXprioriプログラミング 第3回

第3回:XMS2CSVのソースコードを読解する(2)
2006年5月8日 更新


前回は、Xprioriを利用したアプリケーションXML2CSVのソースコードから、XML DBプログラミングの基本的なポイントを学んだ。前回のポイントを押さえていれば、悩むことなくXML DBプログラミングを実践していけるはずだ。


今回は、もう少しXML DBプログラミングの幅を広げてみたい。問い合わせ言語であるXQueryの記述は、XML DBプログラミングにとって重要な要素となる。XML2CSVでは、XMLからCSVへの変換を定義するために、XQueryを自動生成するという特徴的な機能をもっている。XQueryを扱う1つのアプローチとして、自動生成の方法を学ぶことにする。




XML DBプログラミングではXQueryをどうやって作るかが重要

RDBプログラミングではデータベースとの通信はSQLを介して行われるように、XML DBプログラミングではXQueryを使う。どちらも問い合わせ(クエリ)言語の一種だ。以下は、SQLとXQueryの例である。


SELECT * FROM my_table WHERE my_number > 10;
▲RDBで使うSQLの例

for $order in /orders/order
let $price := $order/price/text()
where $price > 1000
return
  <order>

    <number>{$order/number/text()}</number>
    <name>{$order/@name/text()}</name>
    <price>{$price}</price>
  </order>

▲XML DBで使うXQueryの例

XML DBプログラミングでは、XQueryの記述が多くの要素を占める。XMLデータへの問い合わせや更新の条件が複雑になればなるほど、XQueryも長く複雑になるだろう。XQueryをテキストの連結で直にプログラム中に書き込んでいくのが最も基本的な方法だが、別のアプローチもある。


XML2CSVが採用しているのは、XQueryのオブジェクトモデルを作ってXQueryを自動生成するアプローチだ。これなら、プログラム中にXQueryをあらかじめ用意しておかなくとも、条件入力に応じて動的にXQueryを発行することができる。


XML2CSVが採用するXQueryのモデル

XQueryをプログラム中で自動生成するには、XQueryのオブジェクトモデルを作る必要がある。XML2CSVの中で使われているXQueryのオブジェクトモデルを、UMLのクラス図で表すと次のようなものになる。


xml2csv3-1.gif
▲XML2CSVのXQueryオブジェクトモデル


XQueryModelオブジェクトが、生成すべきXQuery全体を表す。このオブジェクトは、中にXQueryForModelオブジェクト、XQueryConditionModelオブジェクト、XQueryReturnModelオブジェクトのリストをもっている。XQueryForModelオブジェクトはXQueryのfor句、XQueryConditionModelオブジェクトはwhere句(の中の条件式)、XQueryReturnModelオブジェクトはreturn句を、それぞれ表している。このように、XQueryの文法が忠実にオブジェクト化されているわけだ。


XQueryの仕様に従ってオブジェクトモデルを一度作ってしまえば、別のアプリケーションでも再利用できるだろう。なお仕様自体はW3CからXQuery 1.0(http://www.w3.org/TR/xquery/)が公開されているが、まだ本稿執筆時点で勧告候補の段階である。


XQuery生成のロジック

オブジェクトモデルを使って、XML2CSVが実際にどうやってXQueryを生成しているのかを見てみよう。以下は、上記オブジェクトモデルのXQueryModelクラス内部のソースコードだ。getQueryメソッドにて、オブジェクトモデルからXQueryの自動生成を行っている。


private List lstFor = null;       // XQueryForModelオブジェクト
private List lstCondition = null; // XQueryConditionModelオブジェクト
private List lstReturn = null;    // XQueryReturnModelオブジェクト
private boolean whereFlag = false;
...中略...
public String getQuery() {
  StringBuffer sb = new StringBuffer();
  // for句の生成
  sb.append(getForStr(true));
  if (this.whereFlag) {
    // where句の生成
    sb.append(getConditionStr());
    ...中略...
  }
  // return句の生成
  sb.append(getReturnStr());
  return sb.toString();
}
▲XQueryオブジェクトモデルからXQueryを生成

やっていることは簡単だ。まずXQueryForModelオブジェクトからfor句を生成し、次にXQueryConditionModelオブジェクトを使ってwhere句を生成する。最後に、XQueryReturnModelオブジェクトを使ってreturn句を生成する。それらを組み合わせて、XQuery全体を構築している。


それぞれの句が、どうやって生成されているかを見てみたい。どの句についても、やるべきプログラミングの内容はそれほど変わりがないので、ここではfor句のみ見ることにする。XQueryModel#getQueryメソッドが呼び出しているgetForStrメソッドの詳細には立ち入らないが、最終的に以下のXQueryForModel#getForStrメソッドが呼び出される。


  private String variable = null; // for句の変数
  private String node = null;     // for句のノード指定
  ...中略...
  public String getForStr() {
    StringBuffer sb = new StringBuffer();
    sb.append("for ");
    sb.append(this.getVariable());
    sb.append(" in ");
    sb.append(this.getNode());
    return sb.toString();
  }
▲XQueryForModelオブジェクトからfor句を生成

for句は基本的に、


for $xxx in /yyy/zzz

のように変数($xxx)とXPathノード指定(/yyy/zzz)とからなる。ここでは、それを素直にモデルから文字列に直している。


このようにして、XQueryに変換可能なオブジェクトモデルを構築しておけば、あとはそのオブジェクトモデルをプログラム実行中にカスタマイズするだけで、さまざまなXQueryを柔軟に発行できるようになるわけだ。重要なポイントは、XQueryのオブジェクトモデルを用意することである。


ただし注意点がある。上記の方法は、時として非常に大きなサイズのXQueryを生成してしまうことがある。Xprioriでは通常、XQueryのサイズに上限が設定されている。この上限値に引っ掛からないよう注意が必要である。また、自動生成されたXQueryは、パフォーマンスの面で最適化されているとは言い難い。パフォーマンスが重視される局面では、自動生成ではなく、直接にXQueryを記述することになる。XQueryを自動生成するか直接記述するかの選択には、柔軟さとパフォーマンスとのトレードオフがあることを覚えておいてほしい。


以上、XML DBプログラミングの重要な要素であるXQueryについて、それを動的に生成するというアプローチをXML2CSVのソースコードから読み解いた。高度なクエリを発行しようとすると、当然XQueryは長大で複雑になっていく。こうした場合に、XQueryを自動生成するアプローチもプログラミング上の選択肢の1つに入れておくとよいだろう。



制作協力:WINGSプロジェクトwingslogo.gif  

▲このページのTOPへ

  • 無償で使える!XMLDB「NeoCore」
  • サイバーテック求人情報
  • メールマガジン申し込み
  • TEchScore

  • ▲NeoCoreについて記載されています!

  • ▲XMLマスター教則本です。試験対策はこれでばっちり!
Copyright (c) CyberTech corporation ltd. All ights Reserved. | サイバーテックについて | ご利用ガイド