|
ここで説明している例は、プロジェクトに含まれているサンプル プロジェクトに基づいています。サンプル プロジェクトを開くための詳細については、「XQuery Mapper サンプル プロジェクトの作成」を参照してください。
XQuery Mapper を使用して、次の図のように、2 つの異なるスキーマのコンテンツを結合できます。

この例では、(CustInfo.xsd で有効な) 顧客データが (PO.xsd で有効な) 反復する要素 line-items と結合されて、POCustInfo.xsd スキーマに対して有効な単一の XML ドキュメントになります。
XQuery Transformations フォルダを右クリックします。/XQuery Transformation/XQueryTransformations です。combineData」と入力し、[次へ] をクリックします。
/XQuery Transformation/XQueryTransformations フォルダに、combineData.xq ファイルが作成されます。
次の図のように、選択したソースとターゲットの要素がデザイン ビューに表示されます。
![]()
|
||
![]()
|
||
![]()
|
||
![]()
|
||
![]()
|
||
![]()
|
||
![]()
|
| 注意 : | 破線は構造的なリンクを表します。このリンクは、データを直接マップせず、親構造間に作成されます。 |
| 注意 : | 実線はデータ リンクを表します。このリンクは、ソース ノードの値をターゲット ノードの値に直接変換します。 |
| 注意 : | 詳細については、「デザイン ビューのグラフィカルな機能」を参照してください。 |
ソース要素とターゲット要素の間のリンクが、次の図のように示されます。
XQuery トランスフォーメーションのテストについては、「データ トランスフォーメーションのテスト」を参照してください。
異なるスキーマ (この例では、PriceQuote.xsd、AvailableQuote.xsd、および taxrate.xsd) に対して有効な XML ファイルのデータを結合し、単一のスキーマ Quote.xsd に対して有効なファイルを作成します。
この手順では、AvailQuote.xsd、PriceQuote.xsd、および taxrate.xsd スキーマを使用して、XQuery トランスフォーメーションを作成します。その後、複数の priceQuote および availRequest ソース要素を対応するターゲット要素にマップします。
XQuery Transformations フォルダを右クリックします。/XQuery Transformation/XQueryTransformations です。Join」と入力し、[次へ] をクリックします。
XQueryTransformation/XQueryTransformations フォルダに Join.xq ファイルが作成されます。
priceQuote/priceRequests および availRequest ソース要素は、共通の要素 widgetId を共有しています。 この手順では、availRequest スキーマの widgetId が priceQuote/priceRequests 要素の widgetId と等しい場合に、クエリがターゲット反復要素 quoteResponse を返す必要のある制限を追加します。
Join.xq を開きます。priceQuote1/priceRequests/priceRequest/widgetId 要素をドラッグし、[ソース] ペインの availRequest1/widgetId 要素にドロップします。
次の図のように、[ソース] ペインの 2 つの widgetId ノードの間を結ぶ線が表示されます。
2 つの widgetId ノードの間のリンクは for ループの where 句で表されます。 where 句は、where 句が true の場合にのみ for ループで式の結果が返される必要があることを指定します。この例では、availRequest 要素の widgetId が priceRequest 要素の widgetId と等しい場合にのみ、quoteResponse 要素で指定された XML データが式によって返されます。
| 注意 : | [制約] ビューで where 句を表示することもできます。 |
現在、quoteResponse 要素は空です。次の手順で要素のコンテンツを追加します。
この手順では、quoteResponse ターゲット要素にデータ リンクを追加します。
デザイン ビューで Join.xq を開き、以下のソース要素とターゲット要素の間のリンクを作成します。
ソース要素とターゲット要素の間のリンクが、次の図のように示されます。

Join.xq ファイルを開きます。 Join 関数呼び出しの間の任意の場所に、以下の関数定義を挿入します。 たとえば、Join 関数宣言の直前に挿入できます。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 には 2 つの関数宣言 calculateTotalPrice および Join が含まれるようになります。 XQuery ファイルに複数の関数が含まれる場合は、XQuery ファイルと同じ名前の関数がデザイン ビューに表示されます。この場合、Join 関数がデザイン ビューに表示されます。 |
xf:calculateTotalPrice($taxRate1,$availRequest/ns1:requestedQuanity,$priceRequest/ns0:price)
式が XQuery の totalCost 要素に追加されます。
[制限] ビューの [Where 句] ペインを使用して制約を作成すると、XQuery で返されるターゲット反復要素を制限できます。 実行時には、where 句の条件を満たす反復要素のみが XQuery の for ループで反復処理されます。
この手順では、for ループの where 句に別の条件を追加して (つまり、複合条件となる)、for ループで返されるデータをさらに制限します。
join.xq ファイルを開きます。availRequest1 ソース要素と quote\quoteResponse ターゲット要素の間のリンクを選択します。
where 句を構成する 1 つの条件が [制限] ビューの [Where 句] ペインに表示されます。
data($priceRequest/ns0:widgetId) = data($availRequest/ns1:widgetId)
availRequest1/requestedQuanity 要素をドラッグし、[Where 句] ペインの [左辺の式] 領域にドロップします。data($availRequest/ns1:requestedQuanity)
< 演算子を選択します。"50"」と入力します。| 注意 : | 引用符で囲まれた数字 50 を入力します (50 ではなく、"50")。 |
[結合の種類] は、where 句を構成する条件が実行時に評価される方法を決定します。
for ループの where 句に、2 つ目の条件が追加されます。where (data($availRequest/ns1:widgetId) = data($priceRequest/ns0:widgetId)
and data($availRequest/ns1:requestedQuanity) < "50")
以下の手順を実行して、where 句の条件が両方とも満たされた場合に XQuery が動作することを確認します。
priceQuote を選択し、[データの生成] アイコンをクリックします。widgetId 要素の値を書き留めておきます。<ns0:widgetId>value</ns0:widgetId>availRequest を選択し、[データの生成] アイコンをクリックします。priceQuote に表示された値と一致するように、テスト XML データの widgetId 要素の値を編集します。<ns0:widgetId>value</ns0:widgetId>
例 : <ns0:requestedQuanity>25</ns0:requestedQuanity>
この例では、[制約] ビューの [和集合] オプションを使用して、同じ型のデータを大きなデータ セットにマップする XQuery を作成します。
XQuery Transformations フォルダを右クリックします。/XQuery Transformation/XQueryTransformations です。union」と入力し、[次へ] をクリックします。PO.xsd\purchase-order] を 2 回選択し、[次へ] をクリックします。| 注意 : | 同じ要素を 2 回以上追加するには、パラメータ名を変更する必要があります。 |
$purchase-order1/line-items/line-item ソース要素と order/items/item ターゲット要素の間のリンクを選択します。| 注意 : | 同じ名前のソース要素とターゲット要素の間にリンクを作成するには、手動でリンクを作成する代わりに、[自動マップ] オプションを使用できます。詳細については、「右クリック メニュー オプション」を参照してください。 |
2 つの構造的なリンクには和集合の制約が適用されているため、図 3-9 に示すように、下位要素の 2 番目のセット間に暗黙的なデータ リンクが生成されます。灰色の実線は、制約の種類として [和集合] を選択して作成された暗黙的なリンクを示します。
XQuery トランスフォーメーションのテストについては、「データ トランスフォーメーションのテスト」を参照してください。
この例では、反復するソース XML 要素を、反復しないターゲット XML 要素にマップします。
次の図に、この例で作成したトランスフォーメーションを示します。

XQuery Transformations フォルダを右クリックします。/XQuery Transformation/XQueryTransformations です。repeatToNonRepeat」と入力し、[次へ] をクリックします。Dates.xsd\dates を選択し、[次へ] をクリックします。PODate.xsd\PODate を選択し、[完了] をクリックします。
次の図のように、repeatToNonRepeat.xq ファイルが作成され、表示されます。
dates1/date 反復要素と [対象] ペインの PODate/billing-date 要素の間のリンクを作成します。dates1/date/type 要素を [制約] ビューの [Where 句] ペインの [左辺の式] 領域にドラッグします。= 演算子を選択します。"BILLING"」と入力し、[追加] をクリックします。dates1/date/value 要素と [対象] ペインの PODate/billing-date 要素の間のリンクを作成します。
前の手順で作成した制約により、XML ドキュメントの dates1/date/type 要素の値が値 "BILLING" と比較するように指定されます。
実行時は、dates1/date/type 要素の値が "BILLING" である場合に、XQuery で dates1/date/value の値が billing-date の値として返されます。
dates1/date 反復要素と [対象] ペインの PODate/delivery-date 要素の間のリンクを作成します。dates1/date/type 要素を [制約] ビューの [Where 句] ペインの [左辺の式] 領域にドラッグします。= 演算子を選択します。"DELIVERY"」と入力し、[追加] をクリックします。dates1/date/value 反復要素と [対象] ペインの PODate/delivery-date 要素の間のリンクを作成します。
前の手順で作成した制約により、XML ドキュメントの dates1/date/type 要素の値が値 "DELIVERY" と比較するように指定されます。
実行時は、dates1/date/type 要素の値が "DELIVERY" である場合に、XQuery で dates1/date/value の値が delivery-date の値として返されます。
XQuery ファイルのテストについては、「データ トランスフォーメーションのテスト」を参照してください。
この例では、反復しないソース要素を、反復するターゲット要素にマップします。
次の図に、この例で作成したトランスフォーメーションを示します。

XQuery Transformations フォルダを右クリックします。/XQuery Transformation/XQueryTransformations です。nonRepeatToRepeat」と入力し、[次へ] をクリックします。PODate.xsd\PODate を選択し、[次へ] をクリックします。Dates.xsd\dates を選択し、[完了] をクリックします。nonRepeatToRepeat.xq ファイルが作成され、表示されます。
以下のコード リストに、生成された XQuery コードを示します。
<ns1:dates>
{for $PODate in $PODate1/ns0:billing-date union $PODate1/ns0:delivery-date
return
<ns1:date/>
}
</ns1:dates>
実行時に、for ループが 2 回実行されます。 最初の実行時に、反復変数 $PODate は和集合の最初の要素 $PODate1/ns0:billing-date と等しくなります。2 回目の実行では、$PODate は $PODate1/ns0:delivery-date と等しくなります。
XQuery はタグ <ns1:date/> を持つ 2 つの空 XML 要素を返します。
以降の手順では、請求日と納期をクエリに返す XQuery コードを追加します。
pODate1/billing-date ソース要素と [対象] ペインの dates/value ターゲット要素の間のリンクを作成します。
pODate1/billing-date から dates/value へのリンクを作成したときに、以下の構造的なリンクが結合されています。
pODate1/billing-date ソース要素と dates/type ターゲット要素の間のリンクを作成します。
次の手順に向けて、pODate1/billing-date から dates/type へのリンクを選択したままにしておきます。
以下の XQuery if-then-else 式がリンクに追加されます。
if (fn:boolean("true")) then
data($PODate)
else
()if セクションの条件を追加します。local-name 関数を、[編集 : If 条件] ペインの [左辺の式] 領域にドラッグします。 関数の $node-var 引数を選択したままにしておきます。PODate 構造リンク変数を、[編集 : If 条件] ペインの [左辺の式] 領域の local-name 関数の $node-var 引数にドラッグします。= 演算子を選択します。"billing-date"」と入力し、[追加] をクリックします。
if-then-else 式の if セクションに、以下の条件が追加されます。
fn:local-name($PODate)="billing-date"
"BILLING" で置き換え、[適用] アイコンをクリックします。"DELIVERY" で置き換え、[適用] アイコンをクリックします。
[式の構造] ペインに、以下の XQuery コードが表示されます。
if (fn:local-name($PODate) = "billing-date") then
"BILLING"
else
"DELIVERY"
XQuery ファイルのテストについては、「データ トランスフォーメーションのテスト」を参照してください。
この例では、ウィジェット ID と州税率に基づいて価格を計算する XQuery トランスフォーメーションを作成します。 以下のロジックを表す if-then-else 式を作成します。
この手順では、PurchaseAgree.xsd および Supplier.xsd スキーマを使用して XQuery トランスフォーメーションを作成します。
XQuery Transformations フォルダを右クリックします。/XQuery Transformation/XQueryTransformations です。ifthenelse」と入力し、[次へ] をクリックします。Supplier.xsd\Supplier を選択し、[次へ] をクリックします。PurchaseAgree.xsd\PurchaseOrder を選択し、[完了] をクリックします。
この手順では、ウィジェット ID が 0 - 200 の場合に価格を $10.00 に指定する If 式を作成します。
supplier1/products/product/price ソース要素と PurchaseOrder/products/product/price ターゲット要素の間のリンクを選択します。supplier1\products\product\widgetID 要素をドラッグし、[左辺の式] ペインにドロップします。>= 演算子を選択します。"0"」と入力し、[追加] をクリックします。<= 演算子を選択します。"200"」と入力します。"$10.00"」と入力します。
以下のコード リストに示すような if-then 式が表示されます。
if ((xs:string(data($product/ns0:widgetId)) >= "0"
and xs:string(data($product/ns0:widgetId)) <= "200")) then
"$10.00"
else
()
この手順では、ウィジェット ID が 201 - 400 の場合に価格を $20.00 にするネストされた If 式を作成します。このためには、前の手順で作成した Else 式の内部にネストされた if-then-else 式を挿入します。
widgetID 要素をドラッグし、[左辺の式] ペインにドロップします。>= 演算子を選択します。"201"」と入力し、[追加] をクリックします。<= 演算子を選択します。"400"」と入力します。"$20.00"」と入力します。
以下のコード リストに示すような if-then-else 式が表示されます。
if ((xs:string(data($product/ns0:widgetId)) >= "0"
and xs:string(data($product/ns0:widgetId)) <= "200")) then
"$10.00"
else
if ((xs:string(data($product/ns0:widgetId)) >= "201"
and xs:string(data($product/ns0:widgetId)) <= "400")) then
"$20.00"
else
()
この手順では、ウィジェット ID が 401 - 600 の場合に価格を $30.00 にするネストされた If 式を作成します。このためには、前の手順で作成した Else 式の内部にネストされた if-then-else 式を挿入します。
Else 句を選択します。この句は、「手順 3. 最初のネストされた If-Then-Else 条件の作成」で作成されています。If 条件を選択します。widgetID をドラッグし、[左辺の式] ペインにドロップします。>= 演算子を選択します。"401"」と入力し、[追加] をクリックします。<= 演算子を選択します。"600"」と入力し、[追加] をクリックします。"$30.00"」と入力し、[適用] アイコンをクリックします。
以下のコード リストに示すようなネストされた if-then-else 式が表示されます。
if ((xs:string(data($product/ns0:widgetId)) >= "0"
and xs:string(data($product/ns0:widgetId)) <= "200")) then
"$10.00"
else
if ((xs:string(data($product/ns0:widgetId)) >= "201"
and xs:string(data($product/ns0:widgetId)) <= "400")) then
"$20.00"
else
if ((xs:string(data($product/ns0:widgetId)) >= "401"
and xs:string(data($product/ns0:widgetId)) <= "600")) then
"$30.00"
else
()
XQuery ファイルのテストについては、「データ トランスフォーメーションのテスト」を参照してください。
この例では、For-Let-Where-Order By-Return 式を使用して、合計値が 2000 を超えるアイテムについて、見積もりからウィジェット ID を抽出します。
XQuery Transformations フォルダを右クリックします。flwor」と入力し、[次へ] をクリックします。Quote.xsd\quote を選択し、[次へ] をクリックします。Quote.xsd\quote を選択し、[完了] をクリックします。| 注意 : | この例では、let 句は必須ではありません。 ここでは XQuery Mapper でのデザイン方法を示すためにのみ使用しています。 |
[式の構造] ペインで [For...Return] を選択すると、FLWOR 式のソース コードを表示できます。以下のコード リストに示すようなコードが作成されます。
for $quote in ($quote1/quoteResponse)let $widget := ($quote/widgetId)where $quote/totalCost > 2000order by $widget ascendingreturn$quote
XQuery トランスフォーメーションのテストについては、「データ トランスフォーメーションのテスト」を参照してください。
この例では、再帰的な要素を含むスキーマを使用してデータ トランスフォーメーションを作成します。
スキーマの要素は、コード リスト 3-8 の例に示すように、親と同じタイプの子要素を含んでいる場合に再帰的と見なされます。この例では、product 要素が再帰的な要素です。これは、この要素のタイプが productType であり、productType にはタイプが同じ productType である child-product 要素が含まれているためです (productType は自身を参照)。
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.acme.org/Product"
xmlns="http://www.acme.org/Product" elementformDefault="qualified"
attributeFormDefault="unqualified">
<xs:complexType name="productType"><xs:sequence>
<xs:element name="part-description" minOccurs="0"
maxOccurs="unbounded" type="xs:string" />
<xs:element name="child-product" minOccurs="0"
maxOccurs="unbounded" type="producttype" />
</xs:sequence>
</xs:complexType>
<xs:element name="product" type="productType">
</xs:element>
</xs:schema>
再帰的なスキーマを使用してトランスフォーメーションを作成するには、以下の手順を実行します。
XQuery Transformations フォルダを右クリックします。/XQuery Transformation/XQueryTransformations です。recursive」と入力し、[次へ] をクリックします。SupplierAcme.xsd\supplier_acme を選択し、[次へ] をクリックします。Product.xsd\product を選択し、[完了] をクリックします。
次の図に、ソース要素と再帰的な child-product ターゲット要素の間のリンクを示します。

XQuery ファイルのテストについては、「データ トランスフォーメーションのテスト」を参照してください。
[キー フィールドによるグループ] 機能を使用して、1 つまたは複数のキー値に基づいてデータをグループ化できます。
| 注意 : | Group-By 機能は XQuery Mapper ではグラフィカルにサポートされておらず、デザイン ビューには XQuery の表現はありません。 ソース ビューで Group-By 式を記述する必要があります。 |
この例では、入力 XML ドキュメントとして以下のコード リストを使用します。
<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>
この例では、input-warehouse-id 要素と input-location-desc 要素をキー フィールドとして使用して、出力ドキュメントのデータをグループ化します。
反復する要素 input-line-item の最初のインスタンスと 3 つ目のインスタンスには、input-warehouse-id 要素と input-location-desc 要素の同じ値 (それぞれ Warehouse1 と Location1) が含まれます。
この例では、コード リスト 3-10 に示すように、出力ドキュメントの Warehouse1 キーと Location1 キーを使用して、ライン アイテムの最初のインスタンスと 3 つ目のインスタンスをグループ化する XQuery を作成します。
<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>
Group-By 式を作成するには、以下の手順を実行します。
XQuery Transformations フォルダを右クリックします。/XQuery Transformation/XQueryTransformations です。groupby」と入力し、[次へ] をクリックします。regroupKeyFldIn.xsd\input-warehouse-inventory を選択し、[次へ] をクリックします。regroupKeyFldOut.xsd\output-inventory を選択し、[完了] をクリックします。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)
groupby.xq ファイルを開いた状態で、テスト ビューを選択します。XML Transformation/XML/ フォルダから) サンプル プロジェクトで提供されている Regrouping.xml ファイルをインポートします。
コード リスト 3-10 に示すように、XQuery の結果が表示されます。
|