|
この節では、BEA XQuery Mapper インストールに含まれるサンプル プロジェクトのシナリオ例を示します。サンプル プロジェクトを開く方法については、「XQuery Mapper サンプル プロジェクト」を参照してください。
XQuery Mapper を使用して、2 つの異なるスキーマのコンテンツを結合できます。次の図 3-1 を参照してください。
この例では、顧客データ (CustInfo.xsd
スキーマで記述されたデータ) が反復する要素 (PO.xsd
スキーマで記述された line-items
) と結合されて、POCustInfo.xsd
スキーマに対して有効な単一の XML ドキュメントになります。
この例では、親フォルダは Sample/XQueryTransformations です。
combineData
」と入力します。 CustInfo.xsd\customer
PO.xsd\purchase-order
POCustInfo.xsd\purchase-order
ソース データとターゲット データを選択すると、combineData.xq
ファイルが作成されます。
|
||
|
||
|
||
|
||
|
||
|
||
|
以下の図で示された破線は構造的なリンクを表します。この種類のリンクは、データを直接マップしない 2 つの親構造間で作成されます。
以下の図で示された実線はデータ リンクを表します。この種類のリンクは、ソース ノードの値をターゲット ノードの値に直接変換します。
リンクの詳細については、「デザイン ビューのグラフィカルな表現について」を参照してください。
ソース要素とターゲット要素間のマップは次の図のように示されます。
XQuery トランスフォーメーションのテストについては、「XQuery ファイルのテスト」を参照してください。
この節では、PriceQuote.xsd
、AvailableQuote.xsd
、および taxrate.xsd
を結合して、単一の Quote.xsd
ファイルを作成します。
この節では、AvailQuote.xsd、PriceQuote.xsd
および taxrate.xsd
ファイルを使用して XQuery トランスフォーメーションを作成します。作成後は、複数の priceQuote
ソース要素と availRequest
ソース要素を、対応するターゲット要素に対してマッピングします。
Join
」と入力します。 PriceQuote.xsd\priceQuote
PriceQuote.xsd\taxRate
AvailQuote.xsd\availRequest
Quote.xsd\quote
ソース データとターゲット データを選択すると、Samples/XQueryTransformations フォルダに Join.xq
ファイルが作成されます。
|
||
|
||
|
||
|
ソース ドキュメント priceQuote
と availRequest
では、共通の要素 widgetId
が共有されます。このサブセクションでは、availRequest
要素の widgetId
が priceRequest
要素の widgetId
と一致する場合に、結合された反復要素 quoteResponse
を返す条件的制約を追加します。
quoteResponse 要素は空です。「手順 3. 空の要素にデータを入力するリンクの追加」で示される手順に従って、quoteResponse
にデータを入力するデータ リンクを追加します。
この節の手順に従って、quoteResponse 要素にデータを入力するデータ リンクを追加します。
この手順では、発注書の総費用額を計算する関数を XQuery ソースに追加します。
Join.xq
ファイルを開きます。 declare function xf:calculateTotalPrice($taxRate as xs:float, $quantity as xs:float,$price as xs:float)
as xs:float {
let $taxQuantity := ($taxRate * $quantity)
let $totalTax := ($taxQuantity * $price)
let $costNoTax := ($quantity * $price)
let $totalCost := ($totalTax + $costNoTax)
return $totalCost
};
Join.xq
ファイルを開きます。 注意 : | Join.xq ファイルには、calculateTotalPrice と Join の 2 つの関数宣言が含まれています。XQ ファイルに複数の関数が含まれる場合は、同じ名前の関数がデザイン ビューに表示されます (この場合、Join 関数がデザイン ビューに表示されます)。 |
xf:calculateTotalPrice($taxRate,$availRequest/ns1:requestedQuanity,$priceRequest/ns0:price)
式が XQuery の totalCost 要素に追加されます。
[制約] タブの [Where 句式] ペインで制約を作成すると、XQuery for
ループに、実行時に返されるターゲット反復要素を制限する where
句を追加できます。
実行時には、複合条件を満たす反復要素についてのみ for
ループが反復処理されます。この節では、for
ループの where
句に別の条件を追加して (複合条件にして)、for
ループによって返される要素をさらに制限します。
join.xq
ファイルを開きます。
where
句を構成する 1 つの条件が [制約] タブの [Where 句式] ペインに表示されます。
data($priceRequest/ns0:widgetId) = data($availRequest/ns1:widgetId)
data($availRequest/ns1:requestedQuanity)
注意 : | 50 を引用符で囲んでください。つまり、「50」ではなく「"50"」と入力してください。 |
[結合の種類] によって、where
句を構成する条件が実行時に評価される方法が決まります。
for
ループの where
句に、2 つ目の条件が追加されます。 where
句を作成します。where (data($availRequest/ns1:widgetId) = data($priceRequest/ns0:widgetId)
and data($availRequest/ns1:requestedQuanity) < "50")
XQuery トランスフォーメーションのテストについては、「XQuery ファイルのテスト」を参照してください。
特にこの例では、以下の手順を完了して、「手順 5. 複数の条件を持つ制約の追加」で設定した両方の制約が満たされる場合にクエリが実行されることをテストする準備を整えます。
<ns0:widgetId>value
</ns0:widgetId>
<ns0:widgetId>value
</ns0:widgetId>
<ns0:requestedQuanity>25</ns0:requestedQuanity>
この例では、[制約] タブで [和集合] オプションを使用して、同じ型のデータを大きなデータ セットにマップする XQuery を作成します。
この例では、親フォルダは Samples/XQueryTransformations です。
union
」と入力します。 PO.xsd\purchase-order
を 2 回選択します)。 PO.xsd\purchase-order
PO.xsd\purchase-order
注意 : | 同じ要素を 2 回追加するには、パラメータ名を変更する必要があります。 |
Order.xsd\order
ソース データとターゲット データを選択すると、union.xq
ファイルが作成されます。
|
||
|
$purchase-order/line-items/line-item
([ソース] ペインの反復する要素) と order/items/item
([対象] ペインの反復する要素) が選択されていることを確認します。part-no
要素と [対象] ペインの part-number
要素の間でリンクを作成します。 注意 : | [ソース] ペインと [対象] ペインで要素の名前が同じである場合は、この手順の説明に従って手動でリンクを作成する代わりに、[自動マップ] 右クリック メニュー オプションを使用できます。詳細については、「リンクのメニュー オプション」を参照してください。 |
2 つの構造的なリンクには和集合の制約が適用されているため、図 3-9 で示されているように、下位要素の 2 番目のセット間に暗黙的なデータ リンクが生成されます。灰色の実線は、[制約] タブの [和集合] を選択して作成された暗黙的なリンクを表します。
XQuery トランスフォーメーションのテストの詳細については、「XQuery ファイルのテスト」を参照してください。
この例では、反復する要素に、反復しない単一の要素をマップする方法を示します。この例では、以下の図に示されているように、反復する XML 要素 (ソース スキーマによって定義) の値を取得し、この要素をターゲット XML ドキュメントの単一の要素 (ターゲット スキーマで定義) にマップするトランスフォーメーションを作成します。
この例では、親フォルダは Samples/XQueryTransformations です。
repeatToNonRepeat
」と入力します。 Dates.xsd\dates
PODate.xsd\PODate
dates/date
) を選択し、[対象] ペインにある最初の反復要素 (PODate/billing-date
) にドラッグします。dates/date/type
ノードを選択して、[制約] タブにある [Where 句式] の [左辺の式] ペインにドロップします。 "BILLING"
」を入力します。
以下の図に示されているように、date の文字列を入力するときは引用符を使用してください。
前の手順で作成した制約により、XML ドキュメントの dates/date/type
要素の値を値 "BILLING" と比較するよう指定されます。
次の手順では、dates/date/type
要素の値が "BILLING" と一致する場合に指定されたデータを返す XQuery コードを for ループに追加します。
dates/date/value
要素を選択し、[対象] ペインにある PODate/billing-date
要素にドラッグします。
このデータ リンクは、実行時に、制約 data($date/ns1:type) = "BILLING"
が true である場合に、billing-date
の値として datesDoc/date/value
の値を返します。
dates/date
) を選択し、[対象] ペインにある 2 番目の反復要素 (PODate/delivery-date
) にドラッグします。dates/date/type
ノードを選択して、[制約] タブにある [Where 句式] の [左辺の式] ペインにドロップします。 "DELIVERY"
」を入力します。次の手順では、実行時に制約が true である場合にデータを返す XQuery コードを追加します。注意 : | 文字列値を入力するときは引用符を使用してください。 |
実行時に、この手順で作成した制約によって、datesDoc/date/type
が文字列 "DELIVERY"
に等しいかどうかがテストされます。
datesDoc/date/value
要素を選択し、[対象] ペインにある PODate/delivery-date
要素にドラッグします。
このデータ リンクは、実行時に、制約 data($date/ns1:type) = "DELIVERY"
が true である場合に、delivery-date
の値として dates/date/value
の値を返します。
XQuery ファイルのテストの詳細については、「XQuery ファイルのテスト」を参照してください。
この例では、反復する要素に反復しない要素をマップする方法を示します。また、実行時に、単一のソース要素を反復するターゲット要素にマップするトランスフォーメーションを作成します。次の図を参照してください。
この例では、親フォルダは Samples/XQueryTransformations です。
nonRepeatToRepeat
」と入力します。 PODate.xsd\PODate
Dates.xsd\dates
ソース データとターゲット データを選択すると、nonRepeatToRepeat.xq
ファイルが作成されます。
<ns1:dates>
{
for $PODate in $PODate1/ns0:billing-date union $PODate1/ns0:delivery-date
return
<ns1:date/>
}
</ns1:dates>
実行時には、上記の XQuery コードの for
ループが 2 回実行されます。最初に for
ループが実行されるとき、反復変数 $PODate
は和集合 $PODate1/ns0:billing-date
の最初の要素と対応し、2 回目に for
ループが実行されるとき、変数 $PODate
は和集合 $PODate1/ns0:delivery-date
の 2 番目の要素と対応します。
上記のクエリで返される XML データは 2 つの空要素 <ns1:date/>
を返します。
以降の手順では、請求日と納期をクエリに返す XQuery コードが追加されます。
pODate/billing-date
要素を選択し、[対象] ペインにある dates/value
要素にドラッグします。
構造的なリンク (pODate/billing-date
から dates/date
へ) と (pODate/delivery-date
から dates/date
へ) が結合されているため、pODate/billing-date
要素から dates/value
要素 (dates/value
) へのリンクを作成したときに、pODate/delivery-date
要素と dates/value
要素の間の 2 番目のデータ リンクが自動的に作成されます。
pODate/billing-date
要素を選択し、[対象] ペインにある dates/type
要素にドラッグします。
次の手順に向けて、pODate/billing-date
から dates/type
へのリンクを選択したままにしておきます。
XQuery if-then-else 構文がリンクに追加されます。たとえば、リンクに対する次のような XQuery ソース コードセグメントが、
data($PODate)
以下の XQuery ソース コードセグメントで置き換えられます。
if (fn:boolean("true")) then
data($PODate)
else
()
$node-var
引数は選択したままにしておきます。pODate
変数を、[If 条件] ペインにある local-name
関数の $node-var
引数にドラッグ アンド ドロップします。 BILLING DATE
"」と入力して [追加] をクリックします。注意 : | 文字列値を入力するときは引用符を使用してください。 |
BILLING
" で置き換えます。data($PODate)
注意 : | "BILLING " 文字列の二重引用符は必ず入力してください。 |
DELIVERY
"」を入力します。注意 : | "DELIVERY " 文字列の二重引用符は必ず入力してください。 |
以下の図に示されているように、XQuery コードが [式の構造] ペインに表示されます。
XQuery ファイルのテストの詳細については、「XQuery ファイルのテスト」を参照してください。
この例では、ウィジェット ID と州税率に基づいて価格を計算する XQuery トランスフォーメーションを作成します。XQuery Mapper を使用して、次の if-then-else ロジックを表す式構造を作成します。
この手順では、PurchaseAgree.xsd
と Supplier.xsd
を使用して新しい XQuery トランスフォーメーションを作成します。
この例では、親フォルダは Samples/XQueryTransformations です。
ifthenelse
」と入力します。 Supplier.xsd\Supplier
PurchaseAgree.xsd\PurchaseOrder
ソース データとターゲット データを選択すると、ifThenElse.xq
ファイルが作成されます。
この手順では、ウィジェット ID が 0 ~ 200 の場合に価格を $10.00 にする If 式を作成します。
[式の構造] ペインで、[If 条件] が強調表示されていることを確認します。
"0"
」と入力します。注意 : | 数値を入力するときは引用符を使用してください。 |
"200"
」と入力します。注意 : | 数値を入力するときは引用符を使用してください。 |
注意 : | [編集 : Then 式] ペインの既存のデータを削除します。「"$10.00"」と入力するときは引用符を使用してください。 |
この手順では、ウィジェット ID が 201 ~ 400 の場合に価格を $20.00 にする、ネストされた If 式を作成します。このためには、「手順 2. 最初の If 条件の作成」で作成した Else 式の内部に、ネストされた If-Then-Else を挿入します。
"201"
」と入力します。注意 : | 数値を入力するときは引用符を使用してください。 |
"400"
」と入力します。注意 : | 数値を入力するときは引用符を使用してください。 |
注意 : | 数値を入力するときは引用符を使用してください。 |
この手順では、ウィジェット ID が 401 ~ 600 の場合に価格を $30.00 にする If 式を作成します。このためには、「手順 3. 最初のネストされた If-Then-Else 条件の作成」で作成した Then 式の内部に、ネストされた If-Then-Else を挿入します。
注意 : | 「手順 3. 最初のネストされた If-Then-Else 条件の作成」で作成した Else 式を必ず選択してください。 |
"401"
」と入力します。注意 : | 数値を入力するときは引用符を使用してください。 |
"600"
」と入力します。注意 : | 数値を入力するときは引用符を使用してください。 |
注意 : | 数値を入力するときは引用符を使用してください。 |
XQuery ファイルのテストの詳細については、「XQuery ファイルのテスト」を参照してください。
この例では、再帰的な要素を含むスキーマを使用してマップを作成する方法を示します。再帰的な要素には、次の図で示されたような親と同じ型の子要素が含まれています。この例では、product
要素のタイプが productType
であり、productType
にはタイプが同じ productType
である child-product
要素が含まれているため (productType
は自身を参照)、product 要素は再帰的です。
この例では、親フォルダは Samples/XQueryTransformations です。
recursive
」と入力します。 SupplierAcme.xsd\supplier-acme
Product.xsd\product
ソース データとターゲット データを選択すると、recursive.xq
ファイルが作成されます。
以下の図に示されているように、product
要素には再帰的な child-product
要素が含まれています。
XQuery ファイルのテストの詳細については、「XQuery ファイルのテスト」を参照してください。
[キー フィールドによるグループ] 機能を使用して、1 つまたは複数のキー値に基づいてデータをグループ化できます。ただし、Group By 機能は XQuery Mapper ではグラフィカルにサポートされておらず、Mapper のデザイン ビューには XQuery の表現はありません。したがって、XQuery Mapper のソース ビューで Group By XQuery 構文を記述する必要があります。
この例では、input-warehouse-id
要素と input-location-desc
要素をキー フィールドとして使用して、出力ドキュメントのデータをグループ化します。
input-warehouse-id
要素と input-location-desc
要素の値と同じ値 (それぞれ Warehouse1
と Location1
) が含まれる。Warehouse1
キーと Location1
キーでグループ化されます (コード リスト 3-3 を参照)。<input-warehouse-inventory xmlns="http://www.creditpo.org/repkeyin">
<input-line-item>
<input-warehouse-id>Warehouse1</input-warehouse-id>
<input-location-desc>Location1</input-location-desc>
<input-part-no>1</input-part-no>
<input-quantity>10</input-quantity>
</input-line-item>
<input-line-item>
<input-warehouse-id>Warehouse2</input-warehouse-id>
<input-location-desc>Location2</input-location-desc>
<input-part-no>2</input-part-no>
<input-quantity>20</input-quantity>
</input-line-item>
<input-line-item>
<input-warehouse-id>Warehouse1</input-warehouse-id>
<input-location-desc>Location1</input-location-desc>
<input-part-no>3</input-part-no>
<input-quantity>30</input-quantity>
</input-line-item>
</input-warehouse-inventory>
<ns0:output-inventory xmlns:ns0="http://www.creditpo.org/repkeyout";>
<ns0:output-warehouse-inventory>
<ns0:output-warehouse-id>Warehouse1</ns0:output-warehouse-id>
<ns0:output-location-desc>Location1</ns0:output-location-desc>
<ns0:output-line-item>
<ns0:output-part-no>1</ns0:output-part-no>
<ns0:output-quantity>10</ns0:output-quantity>
</ns0:output-line-item>
<ns0:output-line-item>
<ns0:output-part-no>3</ns0:output-part-no>
<ns0:output-quantity>30</ns0:output-quantity>
</ns0:output-line-item>
</ns0:output-warehouse-inventory>
<ns0:output-warehouse-inventory>
<ns0:output-warehouse-id>Warehouse2</ns0:output-warehouse-id>
<ns0:output-location-desc>Location2</ns0:output-location-desc>
<ns0:output-line-item>
<ns0:output-part-no>2</ns0:output-part-no>
<ns0:output-quantity>20</ns0:output-quantity>
</ns0:output-line-item>
</ns0:output-warehouse-inventory>
</ns0:output-inventory>
groupby
」と入力します。 regroupKeyFldIn.xsd\input-warehouse-inventory
regroupKeyFldOut.xsd\output-inventory
ソース データとターゲット データを選択すると、groupby.xq
ファイルが作成されます。
注意 : | BEA WebLogic Integration 8.1 リリースの XQuery Mapper では、この時点で input-warehouse-id と output-warehouse-inventory との間のリンクを選択し、[制約の種類|キー フィールドによるグループ] をグラフィカルに選択できましたが、このリリースでは、デザイン ビュー上の表現は使用できません。Group by タイプはサポートされていますが、以下の手順に示すように、該当する XQuery を手動で記述する必要があります。 |
declare namespace ns0 = "http://www.creditpo.org/repkeyin";
declare namespace ns1 = "http://www.creditpo.org/repkeyout";
declare function Regrouping($input-warehouse-inventory as element(ns0:input-warehouse-inventory))
as element(ns1:output-inventory) {
<ns1:output-inventory>
{
for $input-line-item in $input-warehouse-inventory/ns0:input-line-item
group $input-line-item as $group by
$input-line-item/ns0:input-warehouse-id as $key0,
$input-line-item/ns0:input-location-desc as $key1
return
<ns1:output-warehouse-inventory>
<ns1:output-warehouse-id>{ data($key0) }</ns1:output-warehouse-id>
<ns1:output-location-desc>{ data($key1) }</ns1:output-location-desc>
{
for $group0 in $group return
<ns1:output-line-item>
<ns1:output-part-no>{ xs:byte( data($group0/ns0:input-part-no) ) }</ns1:output-part-no>
<ns1:output-quantity>{ xs:byte( data($group0/ns0:input-quantity) ) }</ns1:output-quantity>
</ns1:output-line-item>
}
</ns1:output-warehouse-inventory>
}
</ns1:output-inventory>
};
declare variable $input-warehouse-inventory as element(ns0:input-warehouse-inventory) external;
Regrouping($input-warehouse-inventory)
変更内容はデザイン ビューには表示されません。以下の手順に従って、XQuery をテストします。
[結果データ] ペインで [XQuery のテスト] をクリックします。生成されたデータが [結果データ] タブに表示されます。コード リスト 3-3 に示されたものに類似したキー フィールドでグループ化されたライン アイテムが表示されます (input-warehouse-id は最初のキー、input-location-desc は 2 つ目のキー)。
[デザイン] タブで作成した XQuery トランスフォーメーションは、[テスト] タブを使用してテストできます。XQuery トランスフォーメーションをテストすると、予期される XML 出力または非 XML 出力が適切に生成されたかどうかを確認できます。自動生成された XML ファイル、またはカスタムの XML および非 XML テスト ファイルを使用できます。XQuery のテストの詳細については、「マップ トランスフォーメーションのテスト」を参照してください。
XQuery Mapper では、テストに使用できる XML ファイルが自動的に生成されます。非 XML のテスト ファイルは、自動的に生成されません。詳細については、「カスタム MFL (非 XML) ファイルを使用したテスト」を参照してください。
テスト XML ファイルは、[ソース変数] ドロップダウン リストから使用できます。テスト XML ファイルは、ソース スキーマに基づきます。このファイルは自動的に保存されないため、[エクスポート] アイコンを使用して手動で保存する必要があります。
注意 : | [ソース] タブをクリックして、テスト XML を手動で編集することもできます。 |
ソース データに対して XQuery が実行され、結果が生成されます。結果は、[結果データ] ペインに表示されます。エラーが発生した場合は、問題を示すエラー メッセージが表示されます。
自動生成された XML ファイルがビジネス要件を満たさない場合は、カスタム XML ファイルをインポートできます。
[ファイルのインポート] ダイアログ ボックスが開きます。このボックスを使用して、テストに使用する XML ファイルを検索します。適切なファイルを選択すると、そのファイルは [ソース データ] ペインに表示されます。
テスト データを [ソース データ] ペインにカット アンド ペーストすることもできます。
ソース XML が XQuery に対してテストされ、その結果が表示されます。
XQuery Mapper では、非 XML ファイルは自動的に生成されません。したがって、非 XML スキーマをテストするときは、カスタム非 XML テスト データをインポートする必要があります。
[ファイルのインポート] ダイアログ ボックスが表示されます。このボックスを使用して、テストに使用する非 XML ファイルを検索します。
注意 : | [ファイルの種類] ドロップダウン リストは *.* に変更する必要があります。 |
ソース MFL がターゲット MFL と照合してテストされ、その結果が表示されます。