標準化目前:注目のXML問い合わせ言語
XQuery
 〜中編

 

FLWR表現式の詳細

XQueryを試せるアプリケーション

 今回の記事で例に挙げている問い合わせは、独Software AG社が開発したXQueryのQueryプロセッサである「QuiP」(画面1)を利用して確認した出力結果を掲載しています。QuiPはSoftware AGのQuiPのページからダウンロードして使用することができます。また、ビーコンITでは日本語サイトも準備しているので、ご参照ください(3月14日時点では、まだページはありません)。ただし、QuiPのバージョンにより、シンタックスやアウトプットに多少の違いがあるかもしれませんので、ご了承ください。

画面1 XQueryプロセッサ「QuiP」

for句とlet句の違いは繰り返し

 さて、FLWR表現式を理解するために、もう一度for句とlet句の簡単な例で解説します。for句はin句以下のPath表現式で作成されたシーケンスの値1つ1つを、変数にバインドします。

for $i in (<one/>,<two/>,<three/> )
return
<tuple> { $i } </tuple>

 上記の問い合わせでは、$iに<one/>、<two/>、<three/>が繰り返しバインドされ、3つのタプルを作成します。すなわち、結果として次のようなXML文書が生成されます。

<?xml version="1.0"?>
<xql:result xmlns:xql="http://metalab.unc.edu/xql/">
  <tuple><one /></tuple>
  <tuple><two /></tuple>
  <tuple><three /></tuple>
</xql:result>

 一方、let句はfor句のように繰り返すことはありません。“:=”以降で記述されたPath表現式に対してすべてバインドします。

let $i := (<one/>,<two/>,<three/> )
return
<tuple>
  { $i }
</tuple>

 上記の問い合わせでは、$iに<one/>,<two/>,<three/>のすべてがバインドされ、以下のような結果が作成されます。

<?xml version="1.0"?>
<tuple>
  <one />
  <two />
  <three />
</tuple>

 結果を比べていただければ分かりますが、for句はシーケンス(<one/>, <two/>, <three/>)の中のそれぞれの値に対して繰り返され、return句はそれぞれに呼び出されます。故に結果は3つの<tuple>ノードが生成されました。しかしながらlet句では、繰り返しが発生しませんので、$iにはシーケンス全体がバインドされ、結果としては1つの<tuple>ノードが生成されその子ノードとして、バインドされた3つのノードが存在します。

 for句ではまた、2つの変数にバインドすることにより以下のように直積を作ることが可能です。

for $i in (<i>a</i>,<i>b</i> ) ,
$j in (<j>x</j>,<j>y</j> )
return
<tuple>
  { $i }
  { $j }
</tuple>

 その結果は次のようになります。これはforループがネストされており、for句の外側のバインドに対して、内側のバインドが繰り返されるからです。

<?xml version="1.0"?>
<xql:result xmlns:xql="http://metalab.unc.edu/xql/">
  <tuple> <i>a</i> <j>x</j> </tuple>
  <tuple> <i>a</i> <j>y</j> </tuple>
  <tuple> <i>b</i> <j>x</j> </tuple>
  <tuple> <i>b</i> <j>y</j> </tuple>
</xql:result>

Path表現式とFLWR表現式の違い

 Path表現式とFLWR表現式との違いは、Path表現式では、XML文書に対してフィルタをかけたりノードを指定したり、XML文書の一部を取り出したりすることができますが、まったく新しい構造のXML文書を作り出すことは容易にはできません(スタイルシートである程度はできますが限界があります)。しかしFLWR表現式では、最初の例で示したように、プロジェクト名を<title>タグで表し、プロジェクトの人数を<count>タグで表した、元のXML文書とは異なる構造のXML文書を作り出すことができました。

 このようにFLWR表現式では、元のXML文書の構造とはまったく違う新たなXML文書を生成することができます。

■コラム 複数のXML文書をXMLデータベースでどう扱うか?

 本稿で例として用いたXML文書「projects.xml」は、<projects>ノードがルートとなって、その下に複数の<project>ノードがシーケンス(順番を持った繰り返し)として記述されています。担当者など各プロジェクトの具体的な情報は<project>タグの下に記述されており、<projects>タグは、こうした<project>タグを束ねる役割しかしていないことに注目してください。<projects>タグは、Well-formed(整形式)のXML文書ではルートタグを持つ必要があるため、記述されているのです。

 しかし、こんなに都合良く1つのXML文書ですべてのプロジェクトを管理しているとは限りません。実際の企業では<project>タグごとに別々の文書に分かれていることもあるでしょう。見積書の場合には、個々の見積書が別々の文書になっているのは当然のことで、これらをまとめてXQueryで処理するには、1つの文書にまとめてルートタグを与えなければなりません。

 こうした、複数の同じタイプのXML文書を束ねて<projects>タグのようにルートタグを与える機能が、いくつかのXMLデータベースには備わっています。データベースによりこの方法には多少違いがあります。Software AG社の「Tamino」を例に取ると、データは<project>単位でデータベースに格納され、ユニークなオブジェクトIDが付けられます。<project>の単位は、リレーショナルデータベースでいうところのレコードに相当します。

 Taminoは同じタイプの文書(この場合ルートとして<project>タグを持つXML文書)を、同じDOCTYPEというクラスに格納します。このクラスが、リレーショナルデータベースでいうところのテーブルに相当するものです。

 TaminoにおいてはこのDOCTYPEがルート(XPath 1.0の中ではルートノードであり、XQuery 1.0 and XPath 2.0 Data Modelの中ではドキュメントノードとなる)の役目をしますので、<projects>ノードを記述する必要はありません。下の画面では、<project>は実際に3つのXML文書としてTaminoに格納されています。格納されたXML文書は<project>というDOCTYPE名で管理されます。

 Taminoに対して、本稿で解説したようなXQueryの演算の1つ、選択(selection)のところで説明した例を問い合わせる場合は、DOCTYPE<project>にダイレクトに問い合わせを出すことになります。つまり<projects>というノードを作成する必要はありません。ただしこうした手法はXMLデータベースの種類により違ってくるので、注意してください。

for $p in fromCollection("WebDAV")/project[@start>="2002/02/01"]
let $pn := $p/name/text()
return
<project> <title>{ $pn }</title>
<member>{ $p//member/name } </member>
</project>

 

4/6

Index
注目のXML問合せ言語「XQuery」
  XML問い合わせ言語とデータモデル
・問い合せ言語の役割
・XML問い合わせ言語が求められる理由
・XML問い合わせ言語とデータモデル
・XMLの基本データモデルはツリー構造
  XQuery以前に提案された問い合わせ言語
・XML-QL
・XQL
・XML問い合せ言語として必要な機能
・QuiltとXQuery
  2つの表現式、PathとFLWR
・表現式はシーケンスで表される
・Path表現式
・FLWR表現式
FLWR表現式の詳細
・XQueryを試せるアプリケーション
・for句とlet句の違いは繰り返し
・Path表現式とFLWR表現式の違い
コラム:複数のXML文書をXMLデータベースでどう扱うか?
  SQLとXQueryはどう違う?
・リレーショナルモデルの演算とは
・XQueryの演算
  XQueryにおけるリレーショナルの演算
・リレーショナルモデルの演算とは
・XQueryの演算
・トランスフォーメーション
・次の課題は更新系の命令


XML & SOA フォーラム 新着記事
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

HTML5+UX 記事ランキング

本日月間