by Hippo2000(1999/8/18)
XQLのチュートリアルなのです。基本はXML::XQLモジュールの説明なのですが、XQLの使い方もわかる(かも?)
なおこのドキュメントではXML::XQLモジュールで配布されるtutorial.podにpod2htmlを実行して作成されたファイルをベースにして、編集をくわえて日本語に訳そうとしたものです。わかりにくい部分は本物を見てください。(^^;
原本の著作権はEnno Derksen 氏がお持ちです(詳しくは作者の部分を見てください)。
Enno Derksenさんにはメールで了解をいただきました。なお内容等が間違っていたら修正します。ご連絡ください。
XQL Tutorial - XQL問い合わせの文法についての説明
このドキュメントはXML問い合わせ言語(XQL)の基本的な機能について説明します。XML問い合わせ言語(XQL)の仕様のためのプロポーザルは1998年9月にXSLワーキンググループに提出されています。その仕様は以下のアドレスで見ることが出来ます: http://www.w3.org/TandS/QL/QL98/pp/xql.html。 現時点では単なるプロポーザルであるために、変更になる可能性はあります。しかし最終版はプロポーザルにかなり近いものになるものと思われます。このドキュメントの大半は仕様からそのままコピーしています。
XML::XQL マニュアルページもご覧下さい。
XQL (XML 問い合わせ言語)はXSLパターン言語に自然な拡張を提供します。XSLがノードのクラス識別のために提供した能力に、ブール値のロジック、フィルタ、ノードのコレクションのインデックス化などを加えることによって構築されています。
XQL は特にXML文書のために設計されています。問い合わせ、アドレッシング、パターンに使うことが出来る1つの文法を提供することは問い合わせ言語の一般的な目的です。XQLは簡潔で、簡単で、そして強力です。
XQLは多くのコンテクストで使われるように設計されています。XSLパターンのスーパーセットではありますが、リポジトリを検索したり、他のアプリケーションのために、ノードへのリンクを提供することにも適しています。
XQLという言葉はこのプロポーザルで記述されている言語のために動く言葉であるとに注意してください。この言葉が永遠に使われることを意図していません。同時に、他の問い合わせ言語XML-QLというSQLに非常によく似た文法を使うものもあることに注意してください。
XML::XQLモジュールはXQL仕様にXQL+という機能を加えています。 仕様で記述されているXQLの機能だけを許可するためにはXML::SQL::Strictモジュールをお使い下さい。XQL仕様はコアXQLとXQL拡張とを区別しています。この実装では区別していません、このためStrictモジュールではXQL仕様で記述されている全てを実装しています。Strictモジュールについてのさらに詳しい情報は、XML::XQLのマニュアルページをご覧下さい。このチュートリアルでは、XQL+を参照するときには明示します。
このセクションではコアXQL記法について説明します。これらの機能は全てのXQL実装の一部となり、異なるテクノロジーで使われるための機能の基本的なレベルとして提供されなければなりません。
XQLの基本的な文法はURIディレクトリ・ナビゲーションの文法を真似ていますが、物理的なファイル構造を通したナビゲーションの代わりにXMLツリーでの要素を通したナビゲーションを指定します。
例えば、以下のURIはbarディレクトリにあるfoo.jpgを見つけることを意味します:
bar/foo.jpg
同様に、XQLでは以下の文は要素bazのなかの要素fuzのコレクションを見つけることを意味します:
baz/fuz
このドキュメントを通して、たくさんのサンプルがあります。それらはこのマニュアルページの最後にあるサンプル・ファイルで表されるデータを参照しています。
コンテキスト(context)は問い合わせ演算の対象となるノードの集合体です。Exprオプションを通してXML::XQL::Queryコンストラクタに渡される、完全な問い合わせにとっては、コンテキストはquery()メソッドに渡される入力ノードのリストです。
XQL は入力コンテキトとして、現在のコンテキストを使うのか、「ルート・コンテキスト」を使うのかを選択することが出来ます。「ルート・コンテキスト」はドキュメントの最も根幹となる要素だけをもつコンテキストです。XML::DOMを使うときには、これはDocumentオブジェクトとなります。
デフォルトでは問い合わせは現在のコンテキストを使います。'/'(スラッシュ)が頭に付いた問い合わせはルート・コンテキストを使います。問い合わせはオプションで'./'(ドット、スラッシュ)を使うことによって現在のコンテキストを使うことを明示的に宣言することも出来ます。どちらの書き方もファイルシステムでのディレクトリをナビゲートするために使われる書き方に似ています。
'./'を頭に付けるのは、ある1つの状況でしか必要ありません。問い合わせは再帰的な子孫を示すために'//'演算子を使うことができます。この演算子が問い合わせの先頭にあると、最初の'/'によって、ドキュメントまたはリポジトリのルートの子孫に対して実行されるようになってしまいます。'.//'を前につけることで、現在のコンテキストの子孫に対して問い合わせが実行されます。
./author
以下のものと同じであることに注意してください:
author
このドキュメントのルート要素(bookstore)を見つける:
/bookstore
現在のドキュメントのなかにある、位置に関係なく全てのauthor要素を見つける:
//author
そのbookのstyle属性の値がドキュメントのルートにあるbookstore要素のspecialty属性の値と同じである全てのbookを見つける:
book[/bookstore/@specialty = @style]
XQL式により返されるコレクションは、ドキュメントでの順序、階層、アイデンティティを保ちます。そしてこれらの拡張が定義されています。つまり要素のコレクションは常にドキュメントでの順に繰り返しなしに返されます。
仕様では要素の中の属性の順序については不定であるとしていていますが、この実装では属性もドキュメントでの順序であることに注意してください。さらに詳しい情報についてはXML::XQLマニュアルページのドキュメントでの順序(Document Order)をご覧下さい。
あるタグ名である全ての要素のコレクションはタグ名そのものを使って表すことが出来ます。これについては、'./'で現在のコンテキストからそれらの要素を選択することを示すことによって修飾することができますが、現在のコンテキストが想定されており、明示的に示す必要はあまりありません。
./first-name
first-name
修飾されていない全てのbook要素:
book
全てのfirst.name要素:
first.name
あるタイプの要素のコレクションはパス演算子('/'や'//')を使うことで、指定すること出来ます。これらの演算子は、そこから要素を問い合わせるコレクション(左辺)と、選択する要素を示すコレクション(右辺)を引数として取ります。
子供演算子('/')は左辺のコレクションの直属の要素を選択し、子孫演算子('//')は左辺のコレクションの任意の子孫を選択します。実際において'//'演算子は階層の1つ以上のレベルを置き換えたものと考えることが出来ます。パス演算子は問い合わせが行われるコンテキストを変更することに注意してください。これらを一緒に指定することによってドキュメントを「ドリルダウン」することができるのです。
author/first-name
bookstoreでの1つ以上のレベルが下(任意の子孫)の全てのtilte要素を見つけます:
bookstore//title
これは上記の問い合わせとは違うことに注意してください。これはbookstore要素の孫である全てのtitle要素を見つけます:
bookstore/*/title
bookstoreの中のどこかにあるbook,excerptの中のどこかにあるemph要素を見つけます:
bookstore//book/excerpt//emph
現在のコンテキストでの1つ以上下のレベルにある全てのtitleを見つけます。基本的には、これがピリオドを書かなければならない唯一の状況です:
.//title
名前を使うことなく、'*'コレクションに置き換えることによって、要素を参照することが出来ます。'*'コレクションは、そのタグ名に関係なく、現在のコレクションの全ての子供を返します。
author/*
booksの孫である全てのlast-nameを見つける:
book/*/last-name
現在のコンテキストの全ての孫要素を見つける:
*/*
specialty属性を持っている全ての要素を見つける。この例は副問い合わせを使っていることに注意。これはフィルターと属性でカバーされ、「属性を探す」で説明しています。
*[@specialty]
属性名の前には記号'@'をつけます。XQLは属性とサブ要素を公平に扱うように設計され、2つの種類で機能は可能な限り同等です。
注意:属性はサブ要素を持てません。このため問い合わせの中で、属性にパス演算子を適用することはできません。そのような表現は文法エラーになります。XQL仕様は、属性は階層的に、順序はなく、インデックスは適用できないとしています。しかしこの実装ではそれを許しています。
@style
現在のコンテキストのなかの、price要素のexchange属性を見つけます:
price/@exchange
以下の例は正しくありません:
price/@exchange/total
style属性を持った全てのbookを見つけます。この例では副問い合わせを使っていることに注意してください。これは「フィルター」でカバーしています。
book[@style]
全てのbook要素のstyle属性を見つけます:
book/@style
XQL問い合わせ式にはリテラル値(つまり定数)を入れることができます。数値(=Number
整数、浮動小数点)はXML::XQL::Numberオブジェクトにラップされ、文字列はXML::XQL::Textオブジェクトにラップされます。ブール値
(true() と false()として返される)
はXML::XQL::Booleanオブジェクトにラップされます。
文字列はシングルまたはダブル・クォートで囲まれなければなりません。XQL は特殊文字をエスケープすることを許していないので、シングルとダブル・クォートの両方が入った文字列を作ることは不可能です。これに対応するため、XQL+はq//とqq//というPerlと同じように機能する文字列区切りを加えています。
数値(Numbers)に指数記法は許されていません。この問題を解決するためにはXQL+関数eval()をお使い下さい。詳細はXML::XQLのマニュアルページをご覧下さい。
この実装では、空リストまたは(つまり、空配列へのリファレンス)undefを[]で示します。
234
-456
浮動小数点数値:
1.23
-0.99
文字列:
"some text with 'single' quotes"
'text with "double" quotes'
許されていないもの:
1.23E-4 (XQL+で eval("1.23E-4", "Number") を使ってください)
"can't use \"double \"quotes" (XQL+で q/can't use "double" quotes/ を使ってください)
括弧はわかりやすくするため、または通常の優先順位が操作を表すのに適していないところで使われるグループ化演算子として使うことができます。
フィルターの括弧'[]'をそのコレクションにつけることによって、どんなコレクションにも制約と分岐を適用することが出来ます。フィルタは副問い合わせと呼ばれ、中に問い合わせが入っており、ANYがついたSQLでのWHERE節に似ています。
副問い合わせはブール値に評価され、検査されます。フィルターはコレクションのなかの要素を検査し、副問い合わせの検査に失敗すれば結果のコレクションからはずされます。
簡単にするために、もしコレクションがフィルターの中にあるとき、コレクションになにかメンバーがあればブール値TRUEが生成され、コレクションが空であればFALSEが生成されます。
実際にはauthor/degreeのような式は、以下のような架空の'there-exists-a'メソッドのような、コレクション−ブール値変換関数を適用します。
author[.there-exists-a(degree)]
ある式の与えられたレベルにフィルターはいくつあってもかまいません。空のフィルターは許されません。
book[excerpt]
少なくとも1つのexcerpt要素が入っているbookの全てのtitleを見つける:
book[excerpt]/title
少なくとも1つのexcerpt要素が入っているbookの全てのauthorのうち少なくとも1つのdegreeを持っているauthorを見つける:
book[excerpt]/author[degree]
少なくとも1つのdegreeを持っているauthorを持っている全てのbookを見つける:
book[author/degree]
excerptとtitleを持っている全てのbookを見つける:
book[excerpt][title]
$any$と$all$キーワードを通じて、利用者はany(いずれか1つでも)もしくはall(全ての)のどちらの意味を使うかを明示的に示すことが出来ます。
$any$は集合体のうちのいずれかの要素が条件に合えば、その条件はtrueになることを示します。$all$ではその条件がtrueになるためには、集合体の全ての要素が条件に合わなければいけないということを意味します。
$any$ と $all$ はフィルターの中の副問い合わせの前に現れるキーワードです。
author[last-name = 'Bob']
author[$any$ last-name = 'Bob']
全てのlast-name要素がBobでない、全てのauthor要素を見つける:
author[$all$ last-name != 'Bob']
最初のlast-nameがBobである、全てのauthor要素を見つける:
author[last-name[0] = 'Bob']
XQLはノードの集合体での特定のノードを見つけることを簡単にします。簡単にインデックス番号をカギ括弧で囲みます。番号は0が基準です。
ある範囲の要素を返すことが出来ます。そうするためには、サブスクリプト演算子(カギ括弧)の内側に1つの値ではなく、式を指定します。そのような式は、以下のいずれかをカンマで区切ったものになります:
n n番目の要素を返す
-n 最後の要素からn-1番目の要素を返す
つまり、-1は最後の要素。-2は最後の次の要素。
m $to$ n mからn番目の要素。両端は含まれます。
author[0]
first-nameを持っている3番目のauthor要素:
author[first-name][2]
インデックスは親からの相対であることに注意して下さい。言い換えれば、以下のデータを考えてみて下さい:
<x>
<y/>
<y/>
</x>
<x>
<y/>
<y/>
</x>
以下の式はそれぞれのxの最初のyを返します:
x/y[0]
以下は、全てのxでのyの中からの最初のyを返します:
(x/y)[0]
以下は、最初のxでの最初のyを返します:
x[0]/y[0]
author[0,3]
最初から4番目までのauthor要素を見つけます:
author[0 $to$ 3]
最初、3番目から5番目、そして最後のauthor要素を見つけます:
author[0, 2 $to$ 4, -1]
最後のauthor要素を見つけます:
author[-1]
論理式は副問い合わせの中で使うことが出来ます。例えば論理式を使って、特定の値のノードの全てを見つけたり、ある範囲のノードを持っている全てのノードを見つけたりすること出来ます。
論理式は${op}$という形式をとります。「{op}」のところには{b|a}という形の式がはいるかもしれません。つまり演算子は左辺値と右辺値を引数に取り、ブール値を返します。
XQL拡張のセクションで追加の論理演算子が定義されていることに注意してください。
$and$ と $or$ はブール値のandとorとして機能します。
論理演算子はグループ化の括弧と組み合わせることで、非常に洗練された論理式を構築することが出来ます。
空白は重要ではなく、省略することができ、もしくは以下に示すように分かりやすくするためにいれることができることに注意して下さい。
author[degree $and$ award]
少なくとも1つのdegreeまたはawardを持ち、少なくとも1つのpublicationを持つ全てのauthor要素を探します:
author[(degree $or$ award) $and$ publication]
$not$ は、副問い合わせの中の式の値を否定する論理演算子です。
author[degree $and$ $not$ publication]
publication要素は持っているが、degree要素やaward要素を持たない全てのauthor要素を見つけます:
author[$not$ (degree $or$ award) $and$ publication]
$union$ 演算子(ショートカットは'|')は左辺と右辺の問い合わせからの値の集合体を結合させて返します。重複するものは除かれます。結果のリストはドキュメントでの順序にソートされます。
注意:結合(union)であるので、返される集合体には0もしくは、それ以上のリストの中でのそれぞれの要素タイプの要素を含みます。返される集合体にリストの中に少なくとも1つの要素が入っているように制限するためには、フィルターの節で説明しているフィルターを使って下さい。
$intersect$ 演算子は、2つの集合体に共通の要素の集合体を返します。
first-name $union$ last-name
bookstoreから、すべてのbookとmagazineを見つけます:
bookstore/(book | magazine)
すべてのbookとすべてのauthorを見つけます:
book $union$ book/author
bookまたはmagazineのなかのauthorからfirst-name、 last-name、degreeを見つけます:
(book $union$ magazine)/author/(first-name $union$ last-name $union$ degree)
author/first-nameがBobであるすべてのbookとpriceが10未満であるすべてのmagazineを見つけます:
book[author/first-name = 'Bob'] $union$ magazine[price $lt$ 10]
記号'='は等号のために使われます。 '!=' は等号の否定です。代わりに $eq$ と $ne$を等号と等号の否定に使うことが出来ます。
シングルまたはダブル・クォートを式の中での文字列区切りとして使うことが出来ます。これによって、スクリプト言語のなかからXMLを構築し、渡すことがより簡単に出来るようになります。
要素を比較する値のために、value()メソッドが適用されます。つまり、last-name < 'foo' は本当はlast-name!value() < 'foo'ということを意味します。
フィルターは常にコンテキストを考慮していることに注意して下さい。つまりbook[author]という式は、authorという子供の要素を持っている見つかったすべてのbook要素を意味します。さらにbook[author='Bob']は、その値が'Bob'であるauthorという子供の要素を持っている見つかったすべてのbook要素を意味します。.(ピリオド)を使うことによって、コンテキストの値も検証することが出来ます。たとえばbook[. = Trenton'] はその値が'Trenton'であるすべてのbookを意味します。
author[last-name = 'Bob']
author[last-name $eq$ 'Bob']
from属性がHarvardではない、全てのauthorを見つけます:
degree[@from != 'Harvard']
degree[@from $ne$ 'Harvard']
last-nameが/guest/last-name要素と同じである全てのauthorを見つけます:
author[last-name = /guest/last-name]
テキストが'Mattherw Bob'である全てのauthorを見つけます:
author[. = 'Matthew Bob']
author = 'Matthew Bob'
数値や文字列を比較し、ブール値の結果を返すために、いくつかのバイナリ比較演算子を使うことが出来ます。$lt$, $le$, $gt$, $ge$は未満、以下、より大きい、以上に使われます。大文字/小文字を無視したこれらと同じ演算子があります:$ieq$, $ine$, $ilt$, $ile$, $igt$, $ige$。
<, <=, > そして >= は、ショートカットとして $lt$, $le$, $gt$ そして $ge$ を許しています。
author[last-name = 'Bob' $and$ price $gt$ 50]
from属性が'Harvard'でない全てのauthorを見つける:
degree[@from != 'Harvard']
last-nameがMまたはそれ以上の文字で始まる全てのauthorを見つける:
author[last-name $ge$ 'M']
last-nameが'M'、'm'またはそれ以上の文字で始まる全てのauthorを見つける:
author[last-name $ige$ 'M']
最初の3つのbookを見つける:
book[index() $le$ 2]
10個以上のpublicationを持っている全てのauthorを見つける:
author[publications!count() $gt$ 10]
XQL+ はパターン・マッチのための追加の演算子を定義しています。$match$ 演算子(ショートカットは'=~')は、右辺値で記述されているパターンに左辺値がマッチしていればTRUEを返します。 $no_match$ 演算子(ショートカットは'!~')はマッチすればFALSEを返します。右辺値、左辺値ともに文字列(string)にキャストされます。
右辺値の文字列はPerlでの右辺値の文法に従わなくてはいけません。つまり区切り文字は含まれ、修飾子は許されものでなければなりません。スラッシュ(/)以外の区切り文字を使うときには、'm'を付けなければなりません。右辺値は文字でなければならず、そのためクォートを忘れてはいけません!(そうなければXQL+でのq//またはqq//区切り文字を使って下さい。XML::XQLマニュアルページをご覧下さい)
ここではPerlの置換演算子 s///は使うことが出来ないことに注意して下さい。代わりにXQL+のsubst()関数を使ってみてください。
author[first-name =~ '/[Bb]ob/']
titleに(大文字、小文字を無視して)'Trenton'が入っていない全てのbookを見つける:
book[title !~ 'm!trenton!i']
XQL+で利用できる他の演算子については、XML::XQLマニュアルページをご覧下さい。
比較の左辺値にはベクトルとスカラーが指定できます。比較の右辺値はスカラーまたは実行時にスカラーにキャストできる値でなければなりません。
比較の左辺値が集合体であった場合、比較の演算子はany(いずれかが)という意味で使われます。つまり、その集合体のいずれかの要素が条件にあえばtrueになります。
仕様では式の左辺にはリテラルを許してはいません。つまり '1' = a は許されていません。この実装ではこれを許していますが、これがどれくらい便利なのかよくわかりません。
要素(Element)、属性(attribute)そしてその他のXMLノードタイプは、value()メソッドを適用されることによってテキスト(Text)にキャストされます。value()メソッドはデフォルトではtext()メソッドを呼びます。しかしこの動きはユーザによって変更することが出来ます。value()メソッドは他のXQLデータ型で返すかもしれません。
2つの値を比較するとき、まず最初に同じ型にキャストされます。キャストでの詳細はXML::XQLマニュアルページをご覧下さい。
XQL仕様は、比較時のための値がどのようにキャストされるべきなのかについてあまりはっきりしていません。XQL仕様の執筆者たちとの議論したところ、いくつかの点で合意せず、この点で彼らの実装は食い違っています。この実装はwebMethods社からのJoe Lapp氏のものに一番近くなっています。
XQLは関数(function)とメソッド(method)を区別しています。詳細についてはXML::XQLマニュアルページをご覧下さい。
XQLはコレクションを取り扱う進んだメソッドを提供しています。 これらのメソッドは、集合体とノードについての情報と同様に、特定のノードのコレクションに提供されています。(コレクションメソッドをご覧下さい)
メソッドはmethod(arglist) という形式を取ります。
問い合わせbook[author]について考えてみて下さい。これはauthorを持っている全てのbookを見つけます。形式的には、特定のauthorに関連するbookを、そのauthorのための参照ノードを呼びます。つまり検査されるそれぞれのauthor要素は、book要素のものです。(参照ノードや他の用語の定義についてのより詳細については、付属のXQL BNF Appendixをご覧下さい。XML::XQLマニュアルページもご覧下さい)。メソッドは参照ノードに適用されます。
たとえば、text()メソッドはノードに入っているテキストを構造をはずして返します。(つまり要素その子孫に入っている全てのテキストノードをつなげたものになります)。以下の式は'Bob'という名前のすべてのauthorを返します:
author[text() = 'Bob']
以下は、テキストが'Bob'であるfirst-nameを持っているすべてのauthorを返します:
author[first-name!text() = 'Bob']
以下は'Bob'と名付けられた子供をもつ、すべてauthorを返します:
author[*!text() = 'Bob']
メソッド名は大文字・小文字が区別されます。独自のメソッド、関数を定義する方法についてはXML::XQLマニュアルページをご覧下さい。
以下のメソッドがコレクションのなかのノードについての情報を提供します。これらのメソッドは文字列または数値を返し、副問い合わせでの比較演算子と一緒に使うことも出来ます。
text() メソッドは空白を正規化(normalize)しながら、ノードの子孫のテキストを結合させます。ノードが'preserve'に設定されているxml:space属性を持っているか、最も近い先祖が'preserve'に設定されているxml:space属性を持っていれば、空白は保存されます。空白が正規化されるとき、文字列全体が正規化されます。空白はノードの間でテキストを分けます。エンティティ・リファレンスがドキュメントで使われていると、それが展開されたとき、エンティティ・リファレンスの周りに空白は入りません。この実装では、メソッドは要素ノードのtext()にその要素の子孫のtext()を含むかどうかを示すオプションのパラメータを受け取ることが出来ます。詳細についてはXML::XQLマニュアルページをご覧下さい。
例:
last-nameが'Bob'であるauthorを見つけます:
author[last-name!text() = 'Bob']
これは以下のものと同じです:
author[last-name = 'Bob']
'Matthew Bob'という値をもったauthorを見つけます:
author[text() = 'Matthew Bob']
author[. = 'Matthew Bob']
author = 'Matthew Bob'
この実装では、メソッドは要素ノードのrawText()にその要素の子孫のrawText()を含むかどうかを示すオプションのパラメータを受け取ることが出来ます。詳細についてはXML::XQLマニュアルページをご覧下さい。
以下の例は同じです:
author[last-name!value() = 'Bob' $and$ first-name!value() = 'Joe']
author[last-name = 'Bob' $and$ first-name = 'Joe']
price[@intl!value() = 'canada']
price[@intl = 'canada']
element 1
attribute 2
text 3
entity 6 (XQL仕様にはありません)
PI 7
comment 8
document 9
doc. fragment 10 (XQL仕様にはありません)
notation 11 (XQL仕様にはありません)
DOMではCDATASectionノードは4、EntityReferenceノードは5を返すのに、XQLでは、CDATASectionノードとEntityReferenceノードのどちらも3を返すことに注意して下さい。DOMでのノード型の値を取得するには、XQL+のDOM_nodeType()メソッドをお使いください。ノードの型についてはXML::DOMマニュアルページをご覧下さい。ここでは触れません。
degree[index() $lt$ 3]
degree要素の間に存在するかもしれない他のノードはとばされることに注意してください。
以下のようなデータを考えてみて下さい:
<x>
<y/>
<y/>
</x>
<x>
<y/>
<y/>
</x>
以下の式は各xの最初のyを返します:
x/y[index() = 0]
これは以下のようにしても達成できます(コレクションにインデックスをつけるをご覧下さい):
x/y[0]
book[end()]
各bookの最後のauthorを見つける:
book/author[end()]
bookのauthorの集合全体から最後のauthorを見つける:
(book/author)[end()]
以下のメソッドが名前空間情報を返すためにノードへ適用できます。
仕様では以下のように言っています:ノードの名前空間接頭辞は問い合わせ式の中で、問い合わせ対象のドキュメントの中で、あるいは問い合わせ式と問い合わせ対象のドキュメントの中の両方で定義することが出来ます。もし両方の場所で定義されたならば、その接頭辞は合わないかもしれません。この場合、問い合わせ式で与えられた接頭辞が優先されます。
この実装では問い合わせのために名前空間を定義することは出来ません。したがってこれが起きることはありません。
book
接頭辞myがついたすべてのbook要素を見つけます。この問い合わせは修飾されていないbook要素は返しません:
my:book
authorをサブ要素に持った接頭辞myがついたすべてのbook要素を見つけます:
my:book[author]
接頭辞myがついたauthorをサブ要素に持った接頭辞myがついたすべてのbook要素
my:book[my:author]
接頭辞myがついたすべての要素を見つける:
my:*
すべての名前空間のすべてのbook要素を見つける:
*:book
すべての名前空間からすべての要素を見つける:
*
book要素の中にある接頭辞myがついているstyle属性を見つけます:
book/@my:style
ある要素のすべての属性は@*を使うことによって返されます。これは属性をレコードの中のフィールドとして扱うアプリケーションにとっては、潜在的に便利です。
@*
すべての名前空間のstyle属性を見つける:
@*:style
名前空間myからの要素にある修飾されていない属性も含めて、名前空間myからすべての属性を見つける。
@my:*
このセクションはXQLの関数について定義します。仕様では以下のように言っています:XQLは2種類の関数を定義します。コレクション関数は実施インスタンスの検索コンテキストを使いますが、純粋関数は関数のパラメータを評価するときを除いて、検索コンテキストを無視します。コレクション関数は検索コンテキストの一部に評価しますが、純粋関数は定数値あるいは関数のパラメータにだけ依存する値のどちらかに評価します。
分からなくても気にしない!使ってみて下さい!
コレクション関数はドキュメントのなかのノードのさまざまな型へのアクセスを提供します。これらコレクションはいずれも制約を付けたりインデックスを付けたりすることが出来ます。コレクションは特定の制約に合う参照ノードの子供の集合体を返します。
p/textNode()[1]
ドキュエメントのどこかにある2番目のコメント。ドキュメント・ルートへのコンテキストの設定についての詳細についてはコンテキストをご覧下さい:
//comment()[1]
ancestor(book)
book要素に含まれている、一番近いauthorの先祖を見つけます:
ancestor(book/author)
XQLは日付の値の形式を定義していませんし、また関数がパラメータをどのようにして日付に変換するかも定義していません。この実装では日付を解釈するためにDate::Manipモジュールを使っています。これは想像しうるほとんどの形式を受け付けます。独自の日付実装を組み込むことについてはXML::XQLマニュアルページをご覧下さい。
ホワイトペーパー 'The Design of XQL' by Jonathan Robie,はhttp://www.texcel.no/whitepapers/xql-design.html にあり、順序演算子 ';;' (precedes:先行) と ';' (immediately precedes:直前)について記述しています。これらの演算子はXQL仕様には入っていませんが、なんとかこれらを入れなくてはと思いました。
<TABLE>
<ROWS>
<TR>
<TD>Shady Grove</TD>
<TD>Aeolian</TD>
</TR>
<TR>
<TD>Over the River, Charlie</TD>
<TD>Dorian</TD>
</TR>
</ROWS>
</TABLE>
"Shady Grove'' が入ったTDノードとそのすぐ後に続くTDノードは以下のようになります:
//(TD="Shady Grove" ; TD)
XML::DOMでは、実際には2つのTDノードの間に空白のtextノードがあります。しかしtextノードがxml:spaceをpreserveにしていなければ、この演算子ではそれは無視されます。詳しくは???をご覧下さい。
<SPEECH> <SPEAKER>MARCELLUS</SPEAKER> <LINE>Tis gone!</LINE> <STAGEDIR>Exit Ghost</STAGEDIR> <LINE>We do it wrong, being so majestical,</LINE> <LINE>To offer it the show of violence;</LINE> <LINE>For it is, as the air, invulnerable,</LINE> <LINE>And our vain blows malicious mockery.</LINE> </SPEECH>
以下はSTAGEDIRとそれに続く全てのLINEを返します:
SPEECH//( STAGEDIR ;; LINE )
幽霊(Ghost)を演じている俳優がいつ出ていけばよいかを知りたがっているとします。つまり彼は彼が出ていこうとする直前に誰がどの行を言うかを知りたいとします。STAGEDIRの直前の行では、SPEAKERはその行の前から始まっているかもしれません。この問い合わせでは、先行演算子(;;)をSPEECHでのどこかのLINEの前にあるSPEAKERを識別するために使っています。幽霊は必要とする情報を以下の問い合わせで見つけることが出来ます。それはSPEAKERとLINEそしてSTAGEDIRを選択します。
SPEECH//( SPEAKER ;; LINE ; STAGEDIR="Exit Ghost")
以下の表に演算子を優先順に、最も高い優先順のものを先頭に、同じ優先順をもつ演算子を同じ行にして一覧で示します。この表では関連する演算の効果も載せています。
効果 演算子
---------- -----------
グループ化 ( )
フィルター [ ]
副問い合わせ [ ]
メソッド !
パス / //
マッチ $match$ $no_match$ =~ !~ (XQL+ only)
比較 = != < <= > >= $eq$ $ne$ $lt$ $le$ $gt$
$ge$ $ieq$ $ine$ $ilt$ $ile$ $igt$ $ige$
交差 $intersect$
結合 $union$ |
否定 $not$
論理積 $and$
論理和 $or$
順序 ; ;;
このファイルはXML::XQLの配布といっしょにsamples/bookstore.xmlにも入ります。
<?xml version='1.0'?>
<!-- This file represents a fragment of a book store inventory database -->
<bookstore specialty='novel'>
<book style='autobiography'>
<title>Seven Years in Trenton</title>
<author>
<first-name>Joe</first-name>
<last-name>Bob</last-name>
<award>Trenton Literary Review Honorable Mention</award>
</author>
<price>12</price>
</book>
<book style='textbook'>
<title>History of Trenton</title>
<author>
<first-name>Mary</first-name>
<last-name>Bob</last-name>
<publication>
Selected Short Stories of
<first-name>Mary</first-name> <last-name>Bob</last-name>
</publication>
</author>
<price>55</price>
</book>
<magazine style='glossy' frequency='monthly'>
<title>Tracking Trenton</title>
<price>2.50</price>
<subscription price='24' per='year'/>
</magazine>
<book style='novel' id='myfave'>
<title>Trenton Today, Trenton Tomorrow</title>
<author>
<first-name>Toni</first-name>
<last-name>Bob</last-name>
<degree from='Trenton U'>B.A.</degree>
<degree from='Harvard'>Ph.D.</degree>
<award>Pulizer</award>
<publication>Still in Trenton</publication>
<publication>Trenton Forever</publication>
</author>
<price intl='canada' exchange='0.7'>6.50</price>
<excerpt>
<p>It was a dark and stormy night.</p>
<p>But then all nights in Trenton seem dark and
stormy to someone who has gone through what
<emph>I</emph> have.</p>
<definition-list>
<term>Trenton</term>
<definition>misery</definition>
</definition-list>
</excerpt>
</book>
<my:book style='leather' price='29.50' xmlns:my='http://www.placeholder-name-here.com/schema/'>
<my:title>Who's Who in Trenton</my:title>
<my:author>Robert Bob</my:author>
</my:book>
</bookstore>
ご意見、ご質問はこちらの掲示板で受け付けています。
またメールは河馬屋(Nifty)にお願いします。