|
World Wide Web Consortium (W3C) は、XQuery については、言語に関する機能のセットを定義します。BEA AquaLogic Data Services Platform XQuery エンジンは、1 つの例外 (モジュール) を除き、これらの言語機能を完全にサポートし、関数の強力なサブセットもサポートします。さらに、実装ごとに固有の多くの関数および言語キーワードを追加します。
この章では、XQuery エンジンにおける、関数と言語の実装および拡張について説明します。
AquaLogic Data Services Platform は、2004 年 7 月 23 日の W3C Working Draft 「XQuery 1.0 and XPath 2.0 関数および演算子」 (http://www.w3.org/TR/2004/WD-xpath-functions20040723/) をサポートします。
さらに、AquaLogic Data Services Platform は、XQuery 仕様のエンハンスメントであるまた、次の拡張関数プレフィックスにより識別される複数の関数をサポートします。プレフィックスは fn-bea:
です。たとえば、拡張関数の完全な XQuery 表記は、fn-bea:function_name です。
この節では、BEA XQuery の拡張関数について説明します。以下のトピックがあります。
表 2-1 は BEA XQuery の拡張関数の概要を示します。
AquaLogic Data Services Platform (ALDSP) は、基底の WebLogic Platform のロール ベース セキュリティ ポリシーを使用し、データ リソースへのアクセスを管理します。セキュリティ ポリシーは、保護されたリソースにアクセスするために満たさなければならない条件です。ポリシー、要求されたリソースおよびユーザ コンテキストに従って条件の評価結果が FALSE である場合、当該リソースへのアクセスがブロックされ、関連データは返されません。
AquaLogic Data Services Platform Console を使用していったんセキュリティ ポリシーが構成されると、この節で説明したセキュリティの拡張関数で以下の情報を確認することができます。
この節では、BEA の XQuery 実装における以下の AquaLogic Data Services Platform のアクセス管理拡張関数について説明します。
fn-bea:is-access-allowed
関数は、現在の要求コンテキストに関連するユーザが、リソース名とデータ サービス識別子で示される指定リソースにアクセスできるかチェックします。
fn-bea:is-access-allowed($resource as xs:string, $data\service as xs:string) as xs:boolean
$resource
はリソース名で、また $dataservice
はリソースの識別子です。
この関数は、WebLogic セキュリティ フレームワークにコールし、指定したリソースについてアクセスをチェックします。以下にその例を示します。
if (fn-bea:is-access-allowed("ssn", "ld:DataServices/CustomerProfile.ds"))
then fn:true()
fn-bea:is-user-in-group
関数は、現在のユーザが、指定したグループに存在するかチェックします。この関数は、適切なグループ メンバシップについて、WebLogic で認証された対象を分析します。
fn-bea:is-user-in-group($group as xs:string) as xs:boolean
$group
は現在のユーザに対してテストするグループです。
注意 : | この処理は自動的に認証されません。 |
fn-bea:is-user-in-role
関数は、現在のユーザが指定したグローバル ロールに存在するかチェックします。この関数は WebLogic セキュリティ フレームワークから役割の一覧を取得します。
fn-bea:is-user-in-group($group as xs:string) as xs:boolean
注意 : | この処理は自動的に認証されません。 |
fn-bea:userid()
関数は、保護されたリソースを要求するユーザの識別子を返します。
この節では、BEA の XQuery 実装における以下の期間、日付および時刻の拡張関数について説明します。
fn-bea:date-from-dateTime()
関数は、dateTime
を date
に変換し、dateTime
値の日付部分を返します。
fn-bea:date-from-dateTime($dateTime as xs:dateTime?) as xs:date?
fn-bea:date-from-string-with-format
関数は、指定したパターンに従い、文字列ソース値から新しい date
値を返します。
fn-bea:date-from-string-with-format($format as xs:string?, $dateString as xs:string?) as xs:date?
$format
はパターン、$dateString
は日付です。パターンの指定の詳細については、「日付および時間のパターン」を参照してください。
fn-bea:date-to-string-with-format
関数は、指定したパターンの日付文字列を返します。
fn-bea:date-from-string-with-format($format as xs:string?, $dateString as xs:string?) as xs:date?
$format
はパターン、$date
は日付です。パターンの指定の詳細については、「日付および時間のパターン」を参照してください。
fn-bea:dateTime-from-string-with-format
関数は、指定したパターンに従い、文字列ソース値から新しい dateTime
値を返します。
fn-bea:date-from-string-with-format($format as xs:string?, $dateString as xs:string?) as xs:date?
$format
はパターン、$dateTimeString
は日時です。パターンの指定の詳細については、「日付および時間のパターン」を参照してください。
fn-bea:dateTime-from-string-with-format("yyyy-MM-dd G", "2005-06-22 AD")
は現在の時間帯で指定した日付、12:00:00AM に対応する価を返します。fn-bea:dateTime-from-string-with-format("yyyy-MM-dd 'at' hh:mm", "2005-06-22 at 11:04")
は現在の時間帯で指定した日付、11:04:00AM に対応する価を返します。fn-bea:dateTime-from-string-with-format("yyyy-MM-dd", "2005-July-22")
では、データ文字列が指定したフォーマットに一致しないため、エラーが発生します。fn-bea:dateTime-from-string-with-format("yyyy-MMM-dd", "2005-JUL-22")
は現在の時間帯で 12:00:00AM に対応する価を返します。
fn-bea:dateTime-to-string-with-format
関数は、指定したパターンの日時文字列を返します。
fn-bea:date-from-string-with-format($format as xs:string?, $dateString as xs:string?) as xs:date?
$format
はパターン、$dateTime
は日時です。パターンの指定の詳細については、「日付および時間のパターン」を参照してください。
fn-bea:time-from-dateTime
関数は、dateTime
値から時刻を返します。
fn-bea:date-from-dateTime($dateTime as xs:dateTime?) as xs:date?
fn-bea:time-from-string-with-format
関数は指定したパターンに従い、文字列ソース値から新しい時刻値を返します。
fn-bea:time-from-string-with-format($format as xs:string?, $timeString as xs:string?) as xs:time?
$format
はパターン、$timeString
は時刻です。パターンの指定の詳細については、「日付および時間のパターン」を参照してください。
fn-bea:time-to-string-with-format
関数は指定したパターンの時刻文字列を返します。
fn-bea:time-to-string-with-format($format as xs:string?, $time as xs:time?) as xs:string?
$format
はパターンで、$time
は時刻です。パターンの指定の詳細については、「日付および時間のパターン」を参照してください。
Java クラスの標準記号を使用することにより、日付と時刻のパターンを作成することができます。表 2-2 は使用可能なパターン記号を示しています。
実際の値を表すのに必要な最大文字数に一致するまで各記号を繰り返します。例えば、4 July 2002 を表すパターンは、d MMMM yyyy です。12:43 PM を表すパターンは、hh:mm a です。
この節では、BEA の XQuery 実装における以下の AquaLogic Data Services Platform の実行制御拡張関数について説明します。
fn-bea:async
関数は、バッファを使用して実行スレッド間にデータ フローを制御し、XQuery 式を非同期的に評価します。
fn-bea:async($expression as item()*) as item()*
$expression
は、非同期的に評価する XQuery 式です。
fn-bea:async
関数は、Web サービスの非同期的実行を可能にし、サービスの待ち時間により発生する問題を削減します。
注意 : | 非同期 Web サービスは、トランザクション設定に関係なく、他のスレッドにトランザクション コンテキストを伝播しません。非同期のオペレーションは、同様に新しいトランザクションを開始することはできません。 |
以下の例では、CUSTOMER
はデータベース テーブルで、getCreditScore
関数は 2 つの格付け機関が提供する Web サービスです。
for $cust in db:CUSTOMER()
where $cust/ID eq $param
return
let $score1:= fn-bea:async(exper:getCreditScore($cust/SSN), 2),
$score2:= fn-bea:async(equi:getCreditScore($cust/SSN), 2)
return
if (fn:abs($score1 - $score2) < $threshold)
then fn:avg(($score1, $score2))
else fn:max(($score1, $score2))
fn-bea:fence
関数を使用すると、クエリを複数のアイランドに分割し、その中で境界を越えることのないよう最適化を行い、最適化の境界の定義ができます。クエリを積み重ねる場合にも fn-bea:fence
関数を利用できます。
fn-bea:async($expression as item()*, $cap as xs:integer) as item()*
fn-bea:fence
関数は入力ストリームを変更しない pass-through 関数ですが、グローバルな書き換えがその中で起こらないようオプティマイザに指示を出します。特に、fn-bea:fence
関数は、表示展開 (view unfolding)、ループ展開 (loop unrolling)、定数畳み込み (constant folding) およびブール最適化 (Boolean optimizations) の書き換えを防ぎます。
Timeout 関数は設定が自由に変更できるよう設計されています。エラー条件が発生した場合、関数は単一の $alt
式を返すか、$timeout
および $failure
としてより詳細な情報を返すことができます。
fn-bea-timeout( )
と fn-bea-timeout-with-label( )
の 2 つの関数の相違は、後者はエラー条件発生時に監査情報に加えて $label
を返すことです。
fn-bea:timeout( )
関数には以下の署名があります。
fn-bea:timeout($seq as item()*,
$millisec as xs:integer,
$timeout as item()*,
$failure as item()*) as item()*
$seq
は評価する XQuery の一次式、$millisec
はミリ秒単位でのタイムアウト値、また $timeout
は $seq
の評価が $millis
ミリ秒より長くかかる場合に返されます。$failure
は $seq
の評価にエラーが発生した場合に返されます。
代わりに、$timeout
および $failure
パラメータを単一の $alt
パラメータに置換することができます。$alt
の結果はタイムアウトまたはその他のエラーが発生した場合に返されます。
fn-bea:timeout-with-label( )
関数には以下の署名があります。
fn-bea:timeout-with-label($seq as item()*,
$millisec as xs:integer,
$timeout as item()*
$failure as item(),
$label as xs:string) as item()*
どちらの関数も $seq
の評価が以下のような場合、$seq
の評価結果を返します。
それでもエラーが発生した場合、あるいはミリ秒の制限を越えた場合には、監査記録と共に代替式が返されます。
$millis
または $alt
の評価にエラーが発生した場合は、通常の方法でエラーが報告されます。つまり、どちらの関数も返されたエラーに対する処理を行いません。
クエリにおいて、これらの関数の中の 1 つの関数の特定インスタンスで $seq
の評価にエラーが発生した場合、または「タイムアウト」が発生した場合、同じクエリの評価中、このインスタンスの後続の評価はすべて $timeout
および $failure
(または $alt
) を返します。この場合は、$seq
を再評価することはありません。
データ ソースにアクセスするときにエラーが発生した場合、タイムアウト関数はただちに代替式を返すことに注意してください。
ここで、$param
が外部パラメータである場合の例を示します。
for $cust in db:CUSTOMER()
where $cust/ID eq $param
return
fn-bea:timeout(exper:getCreditScore($cust/SSN), 200,
fn-bea:timeout(equi:getCreditScore($cust/SSN), 200,
fn:error()
)
)
fn:bea:fail-over
および fn:bea:fail-over-with-label
関数は、$seq の評価に例外が発生しない場合、$seq の評価結果を返します。例外が発生する場合は、$alt を返します。どちらも多様関数で、その静的リターン タイプは $seq
および $alt
の静的タイプの組み合わせです。
fn-bea:fail-over($seq as item()*,
$alt as item()*) as item()*
fn-bea:fail-over-with-label($seq as item()*,
$alt as item()*,
$label as xs:string) as item()*
$alt
が返される場合、監査レコードには以下が含まれています。
$seq
の評価によって例外が発生した場合、同じクエリの評価中、このインスタンスに続くすべての評価が $alt
を返します。$seq
の再評価は行いません。$alt の評価によって例外が発生した場合、報告をするだけです。エラー処理を行うことはありません。
fn:bea:fail-over-retry
および fn:bea:fail-over-retry-with-label
関数は、$seq の評価に例外が発生しない場合、$seq の評価結果を返します。例外が発生しない場合は、$alt を返します。
fn:bea:fail-over
および fn:bea:fail-over-with-label
関数とは異なり、fn:bea:fail-over-retry
および fn:bea:fail-over-retry-with-label
関数は、$seq の評価においてエラーが発生しても、以降の各評価の $seq を再評価します。
fn:bea:fail-over-retry
および fn:bea:fail-over-retry-with-label
関数には以下の署名があります。
fn-bea:fail-over-retry($seq as item()*,
$alt as item()*) as item()*
fn-bea:fail-over-retry-with-label($seq as item()*,
$alt as item()*,
$label as xs:string) as item()*
fn-bea:fail-over( )
関数は次の 2 通りの方法で使用できます。
この節では、BEA の XQuery 実装における以下の数字拡張関数について説明します。
fn-bea:format-number
関数は、指定したフォーマット パターンを使用して Double 型を文字列に変換します。
fn-bea:format-number($number as xs:double, $pattern as xs:string) as xs:string
$number
は文字列に変換する Double 型数値、$pattern
はパターン文字列を示します。このパターンのフォーマットは JDK 1.5.0 DecimalFormat
クラスにより指定されます。(DecimalFormat およびその他の JDK 1.5.0 Java クラスに関する情報については、「http://java.sun.com/j2se/1.5.0/」を参照してください。)
fn-bea:decimal-round
関数は、指定した精度 (スケール)、または最も近い整数に四捨五入した 10 進値を返します。
fn-bea:decimal-round($value as xs:decimal?, $scale as xs:integer?) as xs:decimal?
fn-bea:decimal-round($value as xs:decimal?, $scale as xs:integer?) as xs:decimal?
$value
は四捨五入する 10 進値で、$scale
は入力した 10 進値を四捨五入する精度です。1 のスケール値は入力した値を小数点以下第 1 位に、2 のスケール値は小数点以下第 2 位に四捨五入します。
fn-bea:decimal-truncate
関数は、指定した精度 (スケール)、または最も近い整数に切り捨てた 10 進値を返します。
fn-bea:decimal-round($value as xs:decimal?, $scale as xs:integer?) as xs:decimal?
fn-bea:decimal-round($value as xs:decimal?, $scale as xs:integer?) as xs:decimal?
$value
は切り捨てる 10 進値、$scale
は入力した 10 進値を切り捨てる精度です。1 のスケール値は入力した値を小数点以下第 1 位に、2 のスケール値は小数点以下第 2 位に切り捨てます。
この節では、BEA の XQuery 実装における以下の拡張関数について説明します。
fn-bea:get-property
関数は、外部影響に基づいて振る舞いを変更できるデータ サービスの書き込みを可能にします。これは関数をパラメータ化するための暗黙の方法です。
この関数は、最初にプロパティの定義に AquaLogic Data Services Console が使用されているかチェックします。これにあてはまる場合、この値を文字列として返します。プロパティが定義されていない場合は、関数がデフォルト値を返します。
fn-bea:get-property($propertyName as xs:string, $defaultValue as xs:string) as xs:string
$propertyName
はプロパティ名、$defaultValue
は関数が返すデフォルト値です。
fn-bea:inlinedXML
関数はテキスト形式の XML を解析し、XQuery 1.0 Data Model のインスタンスを返します。
fn-bea:inlinedXML($text as xs:string) as node()*
fn-bea:rename
関数は要素名、または要素のシーケンス名を変更します。
fn-bea:rename($oldelements as element()*, $newname as element()) as element()*)
$oldelements
は名前を変更する要素のシーケンス、$newname
は新しい名前とタイプを抽出する要素です。
元のシーケンスの各要素について、fn-bea:rename 関数は以下を含む新規要素を返します。
for $c in CUSTOMER()
return
<CUSTOMER>
{fn-bea:rename($c/FIRST_NAME, <FNAME/>)}
{fn-bea:rename($c/LAST_NAME, <LNAME/>)}
</CUSTOMER>
<CUST><FIRST_NAME>John</FIRST_NAME><LAST_NAME>Jones</LAST_NAME></CUST>
<CUST><FIRST_NAME>John</FIRST_NAME><LAST_NAME>Jones</LAST_NAME></CUST>
この節では、BEA の XQuery 実装における以下の QName 拡張関数について説明します。
fn-bea:QName-from-string
関数は、xs:QName
を作成し、$param
の値をネームスペースなしのローカル名として使用します。
fn-bea:QName-from-string($name as xs:string) as xs:QName
この節では、BEA の XQuery 実装における以下のシーケンス拡張関数について説明します。
fn-bea:interleave
関数は、指定した引数のインターリーブを行います。この関数には以下の署名があります。
fn-bea:async($expression as item()*, $cap as xs:integer) as item()*
$item1
および $item2
はインターリーブする項目です。
例えば、fn-bea:interleave((<a/>, <b/>, </c>), " ")
は以下のシーケンスを返します。
この節では、BEA の XQuery 実装における以下の文字列拡張関数について説明します。
fn-bea:match
関数は、入力された正規表現に一致する文字列に含まれる文字を指定する 2 つの整数のリストを返します (一致する文字が見つからない場合は、空のリスト)。関数が一致する文字を返すと、第 1 整数は一致するサブ文字列の最初の文字のインデックス (位置) を、第 2 整数は一致する文字数を示します。この関数には以下の署名があります。
fn-bea:match($source as xs:string?, $regularExp as xs:string?) as xs:int*
$source
は入力された文字列で、$regularExp
は正規表現の式を使用します。
正規表現の式は標準 java.util.regex.Pattern
クラス パターンを使用します。現在有効な正規表現式コンストラクトへのリンクを以下に示します。
fn-bea:sql-like
関数は、文字列に指定したパターンが含まれているかテストします。通常は、この関数を SQL クエリの述語に使用される SQL LIKE 演算子と同様にクエリの条件として使用することができます。ソース式にパターンが一致した場合、関数は TRUE を返し、そうでない場合は、FALSE を返します。
fn-bea:match($source as xs:string?, $regularExp as xs:string?) as xs:int*
fn-bea:match($source as xs:string?, $regularExp as xs:string?) as xs:int*
$source は検索する文字列、$pattern は SQL LIKE 条件の構文を使用して指定されたパターン、$escape はパターン内のワイルドカード文字をエスケープするために使用する文字です。
パターンを指定するために以下のワイルドカード文字を使用することができます。
エスケープ文字を指定してそれをパターン内の「%」または「_」文字の前に置くことにより、「%」または「_」文字をパターンに含めることができます。関数は、文字をパターン・マッチング用の特殊文字として解釈するのではなく、文字どおりに読み込みます。
$escape 文字は正確に 1 文字の長さで、パーセント文字 (「%」) とアンダースコア文字 (「_」) を用いることはできません。
fn-bea:sql-like($RTL_CUSTOMER.ADDRESS_1/FIRST_NAME,"H%","\")
は、$RTL_CUSTOMER.ADDRESS
内にある、文字 H
から始まるすべての FIRST_NAME
の要素に TRUE
を返します。fn-bea:sql-like($RTL_CUSTOMER.ADDRESS_1/FIRST_NAME,"_a%","\")
は、$RTL_CUSTOMER.ADDRESS
内にある、任意の文字で始まり、2 番目の文字が a
のすべての FIRST_NAME
の要素に TRUE
を返します。fn-bea:sql-like($RTL_CUSTOMER.ADDRESS_1/FIRST_NAME,"H%","\")
は、$RTL_CUSTOMER.ADDRESS
内にある、文字 H%
から始まるすべての FIRST_NAME
の要素に TRUE
を返します。
fn-bea:trim
関数は、先頭と末尾の空白文字を削除します。
fn-bea:match($source as xs:string?, $regularExp as xs:string?) as xs:int*
$source
はトリムする文字列です。$source
が空のシーケンスの場合、関数は空のシーケンスを返します。パラメータが文字列でない場合、AquaLogic Data Services Platform はエラーを生成します。
fn-bea:trim-left
関数は、先頭の空白文字を削除します。
fn-bea:match($source as xs:string?, $regularExp as xs:string?) as xs:int*
fn-bea:trim-right
関数は、末尾の空白文字を削除します。
fn-bea:match($source as xs:string?, $regularExp as xs:string?) as xs:int*
fn-bea:pad-left
関数は、固定長文字列を作成するためパディング文字を文字列の左側に追加します。関数には次の 2 つの種類があります。
入力文字列が要求された長さを超える場合は、そこに収まる長さの従属文字列のみが返されます。
fn-bea:pad-left($str as xs:string?, $size as xs:integer?) as xs:string?
ここでは、文字列 $str
の左側に文字 (ASCII 32) が先頭に付加された、指定数($size
)の文字列が返されます。その結果、$size の長さを持つ文字列となります。この文字列には、$size から fn:長さ ($str) の文字数を差し引いた空白文字を付加した $str が含まれます。
fn-bea:pad-left($str as xs:string?, $size as xs:integer?, $pad as xs:string?) as xs:string?
必要に応じて反復されたパッド文字列 ($pad
) を先頭に付加した任意の数 ($size
) の文字列 ($str
) を返します。
fn-bea:pad-left("abcd", 6, "01")
では、指定された最大 6 文字になるまで、パッド文字列を先頭に付加します。返される文字列は "01abcd"
です。fn-bea:pad-left("abcd", 2, "01")
は、文字が文字列全体に追加されているだけなので、「ab」
のみを返します。この場合、$size
の設定に従って最初の 2 文字のみを返します。fn-bea:pad-left("abc", 6, "01")
は "010abc"
を返します。パッド文字列が一度完全に先頭に付加され、次に指定された長さ ($size) になるまで部分的に付加されています。
fn-bea:pad-right
関数は、固定長文字列を作成するためパディング文字を文字列の右側に追加します。関数には次の 2 つの種類があります。
入力文字列が要求された長さを超える場合は、そこに収まる長さの従属文字列のみが返されます。
fn-bea:pad-right($str as xs:string?, $size as xs:integer?) as xs:string?
ここでは、文字列 ($str
) に文字 (ASCII 32) を付加した指定数 ($size
) の文字列が返されます。その結果、$size の長さを持つ文字列となります。この文字列は、$size - fn:length($str) の空白文字が付加された $str から構成されます。
fn-bea:pad-right($str as xs:string?, $size as xs:integer?, $pad as xs:string?) as xs:string?
必要に応じて反復されたパッド文字列 ($pad
) を先頭に付加した任意の数 ($size
) の文字列 ($str
) を返します。
AquaLogic Data Services Platform には、拡張された XQuery データ モデル (XXDM) をサポートする関数が含まれます。XXDM は、XQuery データ モデル (XDM) のインスタンスおよびインスタンスの変更に関する情報を表します。
この節では、XXDM インスタンスを XDM インスタンスに変換する関数について説明します。
fn-bea:current-value 関数は、指定した引数 (適用された変更に関する情報を除く)の現在の値を表す XDM インスタンスを返します。
fn-bea:current-value($changed as changed-element()) as element()?
fn-bea:old-value 関数は、変更前の指定した引数の値を表す XDM インスタンスを返します。
fn-bea:old-value($changed as changed-element()) as element()?
fn-bea:current-value 関数と fn-bea:old-value 関数は共に多相関数です。
declare function salaryDifference($cus as changed-element
(cus:customer)) as xs:decimal {
fn:data(fn-bea:get-current-value($cus)/salary - fn:data(fn-
bea:get-old-value($cus)/salary)
}
関数は、現在のバージョンの顧客要素と旧バージョンの顧客要素にアクセスし給与を抽出します。さらに抽出した給与を減算してその差を取得します。
XQuery 1.0 仕様書の以下の関数は、現在の BEA XQuery エンジンの実装においてサポートされていません。
この節では、関数および演算子に関する BEA 固有の実装の詳細について説明します。
この節では、BEA XQuery 言語の実装を説明します。以下のトピックがあります。
AquaLogic Data Services Platform は、2004 年 7 月 23 日の W3C Working Draft「XQuery 1.0: An XML Query Language」(http://www.w3.org/TR/2004/WD-xquery-20040723/)、に適合しますが、以下の例外があります。
BEA AquaLogic Data Services Platform での XQuery 言語の実装 (AquaLogic Data Services Platform XQuery エンジン) は、仕様書に適合するだけでなく、以下を通して XQuery 言語を拡張することができます。
BEA は標準 FLWOR 式に group by 句の拡張子を提供します。以下の EBNF は一般的な FLWGDOR 構文を示します。
flwgdorExpression := (forClause | letClause) (forClause
| letClause
| whereClause
| groupbyClause
| orderbyClause)* returnClause
groupbyClause := "group" [variable "as" variable] "by" (expression
["as" variable]) ("," (expression ["as" variable]))*
EBNF フラグメントに参照される残りの句は、XQuery 仕様書に記載された標準定義に従います。
例として、年属性を持たないブックを除外することなく、年単位でブックをグループ化する問題について考えてみます。標準の XQuery を使用すると、fn:distinct-values() 関数の結果を用いて self-join を行い、self-join の結果を年属性のないブックの結果に結びつける必要があります。
以下にこれを実現するために使用する XQuery 式を示します。
let $books := document("bib.xml")/bib/book return (
for $year in fn:distinct-values($books/@year)
return
<g>
<year>{ $year }</year>
<titles>{ $books[@year eq $year]/title }</titles>
</g>,
<g>
<year/>
<titles>{ $books[fn:empty(@year)]/title }
</g>
)
BEA の group by
拡張関数を使用することにより、同じクエリを以下のように表すことができます。
for $book in document("bib.xml")/bib/book
group $book as $partition by $book/@year as $year
return
<g>
<year>{ $year }</year>
<titles>{ $partition/title }</titles>
</g>
以下の表 (表 2-4 および 表 2-5) は、group by 句の適用前後のブックのバインディングを示します。
FLWGOR 式は、概念的にバインディング タプルのシーケンスを構築します。タプルのサイズは FLWGOR にあるその時点での範囲内変数の数です。この例では、group by
句でのタプルは単一の変数バインディング $book
で構成され、bib.xml
ドキュメントにある各ブックに 一度に 1 冊ずつバインドされます (表 2-4 を参照してください)。
group by
はバインディング タプルの新規シーケンスを作成し、各出力タプルには group by
句で定義される変数が含まれます。group by
句の後、それまで範囲内にあった変数はすべて範囲外に移動します。
この例では、group by
句からの出力タプルのサイズは 2 で、その変数バインディングは $year
および $partition
です (表 2-5 を参照してください)。
出力タプル数は、ユニークな group by 値のバインディング数と等しくなります。上記の例では、これはユニークな book/@year
値の数である 2 になります。group
句で指定した変数(上記の例では、$partition
) は、すべての一致する入力値のシーケンスにバインドされます。
この拡張子を使うと、XQuery に生成された XML の外部コンシューマが特定の空の要素と属性を省略できるようになります。これは計算コンストラクタ、条件文およびカスタム関数の代わりに、オプション インジケータを使用することで指定できます。
<a><b>{()}</b><c foo="{()}"/></a>,
<a><c/></a>
<a><b/><c foo=""/></a>
拡張子は直接の要素および属性コンストラクタと共にオプション インジケータ '?' を使用します。これにより、以下においてプロダクション DirElemConstructor
を次のように変更することができます。
[94] DirElemConstructor ::= "<" QName "?"?DirAttributeList
("/>" | (">" DirElemContent* "</" QName S?">")) /* ws: explicit */
同様に、DirAttributeList
を以下のように変更することができます。
[95] DirAttributeList ::= (S (QName "?"?S?"=" S?
DirAttributeValue)?)*
? が存在する場合、子のない要素、および "" の値を持つ属性が省略されます。この例ではクエリが以下のように書き込まれ、
<a><b>{()}</b><c foo="{()}"/></a>,
<a><c/></a>
もう一つの例として、さまざまなタグを使って新規カスタマ要素を作成するケースを考えてみましょう。要件の一つは、元のカスタマに電話番号が存在しない場合、結果のカスタマには電話要素が必要ないということです。標準の XQuery を使用して、以下のように書き込みます。
for $cust in CUSTOMER()
return
<customer>
<id>{ fn:data($cust/C_ID) }</id>
{
if (fn:exists($cust/PHONE))
then <phone>{ fn:data($cust/PHONE) }</phone>
else ()
}
...
</customer>
任意選択の要素コンストラクタを使用すると、以下のように書き込むこともできます。
for $cust in CUSTOMER()
return
<customer>
<id>{ fn:data($cust/C_ID) }</id>
<phone?>{ fn:data($cust/PHONE) }</phone>
...
</customer>
同様に、結果カスタマ要素に要素の代わりに属性を使用する場合、以下に示すように、標準の XQuery を使用して計算属性コンストラクタを使用する必要があります。
for $cust in CUSTOMER()
return
<customer>
<id>{ fn:data($cust/C_ID) }</id>
{
if (fn:exists($cust/PHONE))
then <phone>{ fn:data($cust/PHONE) }</phone>
else ()
}
...
</customer>
任意選択の属性コンストラクタを使用すると、クエリは以下のようになります。
for $cust in CUSTOMER()
return
<customer>
<id>{ fn:data($cust/C_ID) }</id>
<phone?>{ fn:data($cust/PHONE) }</phone>
...
</customer>
この節では、XQuery 言語処理に関する BEA 固有の実装の詳細について説明します。