![]() ![]() ![]() ![]() |
ここで説明している例は、プロジェクトに含まれているサンプル プロジェクトに基づいています。サンプル プロジェクトを開くための詳細については、「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 > 2000
order by
$widget ascending
return
$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 の結果が表示されます。
![]() ![]() ![]() |