XQuery

XQueryとは、XMLデータに問い合わせを行うための言語です。表現式(Expression)を基本単位として、いくつかの表現式を組み合わせたり、入れ子にしたりしながら記述する関数型言語です。表現式の値は常にシーケンスで表せます。

Table of Contents

  1. Path表現式
  2. FLWOR表現式
    1. for
    2. let
    3. where
    4. order by
    5. return

シーケンス

シーケンスとは、単純な値かまたはノード(要素や属性)の0個以上の集まりで、順序性を保持しています。値や変数、ノードをカンマで区切って羅列することで、シーケンスを作成することができます。

例えば、3つの整数1、2、3から成るシーケンスは(1,2,3)と表現することができます。このシーケンスを返すFLWOR表現式は次のようになります。

for $x in (1,2,3) return $x

シーケンスには順序性がありますので、(1,2,3) と (3,2,1) は異なるシーケンスとなります。

整数値シーケンスの演算

to演算子により、連続する整数のシーケンスを作成できます。to演算子は被演算子として2つの整数を取り、その2つの整数とその間の全ての整数を含むシーケンスを作成します。

例えば、5つの整数1、2、3、4、5から成るシーケンスは(1 to 5)と表現することができ、このシーケンスを返すFLWOR表現式は次のようになります。

for $x in (1 to 5) return $x

ノードシーケンスの演算

以下の演算子により、ノードシーケンスの演算を行えます。各演算子は2つの被演算子を取ります。

演算式意味
unionどちらかの被演算子に出現するノードを全て含むシーケンスを返します。
intersect両方の被演算子に出現する要素を全て含むシーケンスを返します。
except最初の被演算子に出現して、2番目の被演算子に出現しないノードを全て含むシーケンスを返します。

$seq1 = (A,B) , $seq2 = (B,C)
$seq1 union $seq2 = (A,B,C)
$seq1 intersect $seq2 = (B)
$seq1 except $seq2 = (A)

XQueryの代表的な表現式には以下の2つがあります。

Path表現式

Path表現式は大きく分けて2つの操作を目的としています。1つは特定のノード(要素、属性、テキスト)を指定することであり、もう1つは条件を指定して該当するデータを取り出すことです。

XPath

基本表現

XQuery の基本表現は以下のものを使用します。

コメント(注釈)は {-- と --} で囲んで記述します。

{-- コメント --}

XQuery 1.0はXPath 2.0をサブセット(部分集合)として含んでいます。ノードを指定するにはXPathを使用します。

XML文書の取り込み

XQueryにXML文書を指定するには代表的なものとして以下の3つの方法があります。

アプリケーションがXML文書をユーザーに指定させる方法を有している場合は、input 関数を使用します。

XML文書のファイルパスを指定する場合は、document 関数を使用します。

XML文書のURIを指定する場合は、collection 関数を使用します。

XML文書の作成

XQueryで静的にXML文書を作成する場合は以下の例のように単純にXML文書を記述する方法があります。

<book isbn="4-89471-319-5">
  <title>詳解UNIXプログラミング</title>
  <author>
    <first>W</first>
    <last>スティーヴンス</last>
  </author>
</book>

XPathなどで動的にXMLを作成する場合は"{","}"で囲った中に動的な部分を記述します。

<example>
<p> Here is a query. </p>
<eg> $i//title </eg>
<p> Here is the result of the above query. </p>
<eg>{ $i//title }</eg>
</example>

上の例は以下のようになります。

<example>
<p> Here is a query. </p>
<eg> $i//title </eg>
<p> Here is the result of the above query. </p>
<eg><title>Harold and the Purple Crayon</title></eg>
</example>

FLWOR表現式

FLWOR表現式にはfor句、let句、where句、order by句、return句があります。

FLWOR表現式は以下の様に記述します。

1つ以上のlet句またはfor句
where句 (省略可)
order by句 (省略可)
return句

for 句

for句は変数に複数のシーケンスを1つずつ代入して同じ処理を複数回繰り返す場合に使用します。

for句は以下のように記述します。

for 変数名 in Path表現式

for句は繰り返しを表します。変数名は必ずドル通貨記号 ($) で始まります。for句の中のin句のPath表現式で作成されたシーケンスの各要素の対して繰り返し、 変数をバインドします。バインドされた変数はタプルを作成し、作成されたタプルは順番を持ったシーケンスになります。 また、属性やテキストも変数にバンドすることができます。

for $s in (<one/>, <two/>),$t in(<three/>,<four/>)

上の例の場合は変数$s,$tの組み合わせで(<one/>,<three/>)と(<one/>,<four/>)と(<two/>,<three/>)と(<two/>,<four/>)として4回繰り返します。

for句に他のFLWOR表現を入れ子にすることもできます。次の例では、ある出版社(pubulisher)の著者名(author)を昇順で出力しています。

for $x in let $y := /bookshelf/book[publisher/text()="岩波書店"] return distinct-values($y/author/text())
order by $x
return $x

let 句

let句は変数にシーケンスを代入する場合に使用します。

let句は以下のように記述します。

let $variable := expression , $variable := expression , ......
let $s := (<one/>, <two/>, <three/>)

where 句

where句は処理する条件を指定する場合に使用します。

where 条件式

where句はfor句とlet句で作成されたタプルに対してフィルタをかけます。Path表現式ではオリジナルのXML文書にフィルタ をかけるのに対して、where句ではfor句およびlet句で作成されたタプルに対してフィルタをかけます。 対象要素に対して条件を適用し、trueであった場合は対象要素を残し、falseであった場合は対象要素を捨てます。

条件式には andor といった論理演算子を用いて複数の条件を指定することができます。

for $x in /bookshelf/book
where $x/price > 500 and $x/price < 1000
return $x/title

where句にも以下のような入れ子表現が可能です。where句の場合の入れ子は、「そのサブクエリが結果として空シーケンスでないか」によってフィルタをかけるだけです。

for $x in /bookshelf/book
where for $y in $x/title return $y
return $x

このようなクエリで、where句内の入れ子における出力となる$yがなければ、つまり /bookshelf/book/title 要素が存在すれば trueとなり、そうでなければfalseになります。それらのフィルタリングは$xそれぞれに対して行われます。この場合、空シーケンスでないことがフィルタリング条件であり、件数には依存しません。

order by 句

order by句は処理する順番を指定する場合に使用します。

order by node 順序

nodeにはソート(並び替え)対象となるノードを指定します。 順序には ascending (昇順) か descending (降順) を指定します。順序を省略した場合は昇順に並び替えられます。

ソート条件はカンマ記号で区切って複数記述することができます。第1引数、第2引数、・・・の順にソート基準が決定されます。

for $x in /bookshelf/book
order by $x/author, $x/title
return $x

このクエリでは、まずauthorの値によってソートされ、authorの値が同じものに対してはtitleの値によってソートされます。

return 句

return句は結果の作成を行います。return区はfor句とlet句で作成された1タプルに対して1回呼び出されます。

結果は要素コンストラクタで記述されます。要素コンストラクタでは、変数を用いて要素名、属性名、要素値、属性値のバインドも行えます。また、直接定数値などを埋め込むこともできます。

return constructor

コンストラクタの記述では、タグに挟まれたデータを返却する場合は"{"と"}"で囲んで記述します。