![]() ![]() ![]() ![]() |
この手順では、既存のクエリにさらにマッピングを追加します。これまでの節では、PriceQuote.xsd
XML スキーマで定義されたソースの型から、Quote.xsd
XML スキーマで定義された対象の型に一部のデータをマップしました。この節では、次の図のように、PriceQuote.xsd
XML スキーマ、AvailQuote.xsd
XML スキーマ、および Java float プリミティブ taxRate
で定義されたソースの型から、Quote.xsd
XML スキーマで定義された対象の型にさらにデータをマップします。
この節で作成されるマッピングでは、ソース XML スキーマおよび対象 XML スキーマの繰り返し要素間の結合が作成されます。以下のタスクを実行して、結合を作成、テスト、および変更します。
このタスクでは、MyTutorialJoin トランスフォーメーション ファイルに、要求されたウィジェットの税込みの合計金額を計算するユーザ定義 Java メソッドを作成します。「calculateTotalPrice ユーザ メソッドをクエリで呼び出すには」では、このメソッドを呼び出すようにクエリを変更します。
MyTutorialJoin.java
を選択します。
ユーザ メソッドが MyTutorialJoin トランスフォーメーション ファイルに作成されます。
newusermethod1
という新しいメソッドがソースに追加されます。このメソッドの名前を calculateTotalPrice
に変更します。calculateTotalPrice
Java メソッドに移動します。public java.lang.String calculateTotalPrice() {
return "";
}
このメソッドを次の calculateTotalPrice
Java メソッドに置き換えます。
public static float calculateTotalPrice(float taxRate, int quantity, float price, boolean fillOrder)
{
float totalTax, costNoTax, totalCost;
if (fillOrder)
{
// 合計税額を計算する
totalTax = taxRate * quantity * price;
// 税抜きの合計代金を計算する
costNoTax = quantity * price;
// 税額と代金とを加算して、合計金額を取得する
totalCost = totalTax + costNoTax;
}
else
{
totalCost = 0;
}
return totalCost;
}
注意 : | calculateTotalPrice 関数の戻り値の型を、必ず String から float に変更してください。 |
myJoin.xq
を表示します。
これらのノードは両方とも繰り返しノードです。繰り返しノードでは、このノードの複数のインスタンスを指定できます。繰り返しノードはノードの右側に + 記号が付くことで表されます。
警告 : | priceRequests ノードではなく、priceRequest ノードを選択する必要があります。 |
次の図のように、2 つの繰り返しノードをつなぐ破線が表示されます。
短い線の破線は、構造的なリンク (データを直接マップしない 2 つの親構造間のリンク) を表します。
XML の繰り返しノードの詳細については、「XML の繰り返しノードについて」を参照してください。
次の図のように、2 つの繰り返し要素をつなぐ破線が表示されます。
declare namespace xf = "http://tempuri.org/Tutorial_Project_Web/src/requestquote/myJoin/";
declare namespace ns0 = "http://www.example.org/price";
declare namespace ns1 = "http://www.example.org/avail";
declare namespace ns2 = "http://www.example.org/quote";
declare function xf:myJoin($priceQuote1 as element(ns0:priceQuote),
$availQuote1 as element(ns1:availQuote),
$taxRate as xs:float)
as element(ns2:quote) {
<ns2:quote>
<name>{ data($priceQuote1/ns0:customerName) }</name>
<address>{ concat($priceQuote1/ns0:shipAddress/@street ,",", $priceQuote1/ns0:shipAddress/@city ,",", fn:upper-case($priceQuote1/ns0:shipAddress/@state) , ",",$priceQuote1/ns0:shipAddress/@zip) }</address>
{
for
$priceRequest in $priceQuote1/ns0:priceRequests/ns0:priceRequest,
$availRequest in $availQuote1/ns1:availRequest
return
<quoteResponse
/>
}
</ns2:quote>
};
declare variable $priceQuote1 as element(ns0:priceQuote) external;
declare variable $availQuote1 as element(ns1:availQuote) external;
declare variable $taxRate as xs:float external;
xf:myJoin($priceQuote1,
$availQuote1,
$taxRate)
上のクエリでは、繰り返しノードの子の間のデータ リンクは存在しません。そのため、quoteResponse
要素は空になっています (文字列 <quoteResponse/>
は空のノードです)。
繰り返しノード間の構造的なリンクでは、for
ループが生成されます (for ループは上のクエリのリストで太字で示されています)。この XQuery for
ループは、priceRequest
繰り返し要素と availReqest
繰り返し要素のセットを反復処理します。たとえば、このクエリのソース XML データに priceRequest
要素の 3 つのインスタンスと availRequest
要素の 3 つのインスタンスが含まれている場合、for
ループは以下の合計 9 回の結合を実行します。
priceRequest
要素の最初のインスタンスと、availRequest
要素の最初のインスタンスを結合する。priceRequest
要素の最初のインスタンスと、availRequest
要素の 2 番目のインスタンスを結合する。priceRequest
要素の最初のインスタンスと、availRequest
要素の 3 番目のインスタンスを結合する。priceRequest
要素の 2 番目のインスタンスと、availRequest
要素の最初のインスタンスを結合する。priceRequest
要素の 2 番目のインスタンスと、availRequest
要素の 2 番目のインスタンスを結合する。priceRequest
要素の 2 番目のインスタンスと、availRequest
要素の 3 番目のインスタンスを結合する。priceRequest
要素の 3 番目のインスタンスと、availRequest
要素の最初のインスタンスを結合する。priceRequest
要素の 3 番目のインスタンスと、availRequest
要素の 2 番目のインスタンスを結合する。priceRequest
要素の 3 番目のインスタンスと、availRequest
要素の 3 番目のインスタンスを結合する。
トランスフォーメーションではクエリを使用してすべての可能な結合を生成できますが、トランスフォーメーションによっては次の手順で説明するように結合に制約を付けることもできます。
次の図のように、2 つの widgetId ノード間にリンクが表示されます。
declare namespace xf = "http://tempuri.org/Tutorial_Process_Application_Web/src/requestquote/myJoin/";
declare namespace ns0 = "http://www.example.org/price";
declare namespace ns1 = "http://www.example.org/avail";
declare namespace ns2 = "http://www.example.org/quote";
declare function xf:myJoin($priceQuote1 as element(ns0:priceQuote),
$availQuote1 as element(ns1:availQuote),
$taxRate as xs:float)
as element(ns2:quote) {
<ns2:quote>
<name>{ data($priceQuote1/ns0:customerName) }</name>
<address>{ concat($priceQuote1/ns0:shipAddress/@street ,",", $priceQuote1/ns0:shipAddress/@city ,",", fn:upper-case($priceQuote1/ns0:shipAddress/@state) , ",", $priceQuote1/ns0:shipAddress/@zip) }</address>
{
for $priceRequest in $priceQuote1/ns0:priceRequests/ns0:priceRequest,
$availRequest in $availQuote1/ns1:availRequest
where
data($priceRequest/ns0:widgetId) = data($availRequest/ns1:widgetId)
return
<quoteResponse/>
}
</ns2:quote>
};
declare variable $priceQuote1 as element(ns0:priceQuote) external;
declare variable $availQuote1 as element(ns1:availQuote) external;
declare variable $taxRate as xs:float external;
xf:myJoin($priceQuote1,
$availQuote1,
$taxRate)
widgetId ノード間のリンクによって、for
ループ内に where
句が生成されます (where 句は上のクエリのリストで太字で示されています)。この where
句は for
ループの出力に制約や制限を付けます。特に where
句は、where
句内の式が true の場合に、for
ループが return
の内容を出力することを指定します。この例では、availRequest 要素の widgetId
が priceQuest の widgetId
と一致する場合に、次の XML データが返されます。
<quoteResponse/>
空の quoteReponse
要素はあまり使いやすくありません。次のタスク「quoteResponse 要素に入れるリンクを追加するには」では、quoteResponse
要素に入れるデータ リンクを追加します。
注意 : | 次の節では、注文の合計金額を計算するため、taxRate Java プリミティブと quote/quoteResponse/totalCost ノードの間のリンクを編集します。 |
[一般式] ペインで、デフォルト引数 $float-var が $taxRate 引数に置き換えられて、次の引数が選択されます。
[一般式] ペインで、デフォルト引数 $int-var が $availRequest/ns1:requestedQuantity 引数に置き換えられて、次の引数が選択されます。
[一般式] ペインで、デフォルト引数 $float-var が $priceRequest/ns0:price 引数に置き換えられて、次の引数が選択されます。
[一般式] ペインで $boolean-var
を選択します。
図 5-5 に示すように、[一般式] ペインで、デフォルト引数 $boolean-var が $availRequest/ns1:quantityAvail 引数に置き換えられます。
デザイン ビューで、図 5-6 のように表示されます。
declare namespace xf = "http://tempuri.org/Tutorial_Process_Application_Web/src/requestquote/myJoin/";
declare namespace ns0 = "http://www.example.org/price";
declare namespace ns1 = "http://www.example.org/avail";
declare namespace ns2 = "http://www.example.org/quote";
declare function xf:myJoin($priceQuote1 as element(ns0:priceQuote),
$availQuote1 as element(ns1:availQuote),
$taxRate as xs:float) as element(ns2:quote)
{
<ns2:quote>
{
<name>{ data($priceQuote1/ns0:customerName) }</name>
<address>{ concat($priceQuote1/ns0:shipAddress/@street ,",", $priceQuote1/ns0:shipAddress/@city ,",", fn:upper-case($priceQuote1/ns0:shipAddress/@state) , ",", $priceQuote1/ns0:shipAddress/@zip) }</address>
{
for $priceRequest in $priceQuote1/ns0:priceRequests/ns0:priceRequest,
$availRequest in $availQuote1/ns1:availRequest
where data($priceRequest/ns0:widgetId) = data($availRequest/ns1:widgetId)
return
<quoteResponse>
<widgetId>{ data($priceRequest/ns0:widgetId) }</widgetId>
<unitPrice>{ data($priceRequest/ns0:price) }</unitPrice>
<requestedQuantity>{ data($availRequest/ns1:requestedQuantity) }</requestedQuantity>
<fillOrder>{ data($availRequest/ns1:quantityAvail) }</fillOrder>
</quoteResponse>
{
for $shipDate in $availRequest/ns1:shipDate
return
<shipDate>{ data($shipDate) }</shipDate>
}
<taxRate>{ $taxRate }</taxRate>
<totalCost>{ calculateTotalPrice($taxRate,
$availRequest/ns1:requestedQuantity,
$priceRequest/ns0:price,
$availRequest/ns1:quantityAvail) }</totalCost>
}
</ns2:quote>
前の手順で追加されたリンクによって、<quoteResponse>
タグと </quoteResponse>
タグの間に追加の XQuery ソース コードが生成されています (追加ソースは上のクエリのリストで太字で示されています)。
myJoin トランスフォーメーション メソッドに渡す重要な 3 つのパラメータ、$priceQuote1、$availQuote1、および $taxRate があります。「単純なクエリをテストするには」のタスクで、$priceQuote1
パラメータのソース データとして PriceQuote.xml
をインポートしました。
$availQuote1
用に AvailQuote.xml
をインポートします。
テスト XML データを使用して、クエリが実行されます。図 5-7 のように、生成された XML データのグラフィカルな表現が [結果データ] ペインの [XML デザイン ビュー] に表示されます。
このクエリは、ソース繰り返し要素の 2 つのセット (availRequest および priceRequest) を、1 つの繰り返し要素 (quoteResponse) に結合します。
XML データが対象の XML スキーマに対して有効であるかどうかが、[出力] タブに表示されます。この例では、生成された XML データが Quote.xsd
ファイルの XML スキーマに対して有効であるかどうか確認されます。
このタスクでは、MyTutorialJoin.java
コントロールのインスタンスを作成します。
注意 : | XQuery トランスフォーメーション パースペクティブからプロセス パースペクティブに切り替えて、コントロールを作成します。[ウィンドウ|パースペクティブを開く|その他|プロセス パースペクティブ] をクリックします。 |
Tutorial_Process_Application_Web\src\requestquote\RequestQuote.java
に移動し、RequestQuote.java をダブルクリックします。
MyTutorialJoin.java というインスタンスがプロジェクト内に作成され、次の図のように [コントロール] ペインに表示されます。
このタスクでは、RequestQuote ビジネス プロセス内の [Combine Price and Avail Quotes] ノードを編集し、このノードによって呼び出されるインスタンスを、TutorialJoin.java
のインスタンスから MyTutorialJoin.java
のインスタンスに変更します。さらに、MyTutorialJoin コントロールの myJoin()
メソッドを呼び出すように、[Combine Price and Avail Quotes] ノードの設計を変更します。myJoin()
メソッドは、異なるシステムからビジネス プロセスに返されるデータを結合して、1 つの XML 応答ドキュメント (見積もり) を作成します。作成されたドキュメントはビジネス プロセスのクライアントに返されます。
QuoteDocument
myJoin()
を選択します。
[割り当てる変数を選択します] フィールドにデフォルトの変数が表示されます。次のリストに示すように、データ型は myJoin
() メソッドのソース パラメータで想定されているデータ型と一致します。
priceQuote には、ビジネス プロセスの For Each ループにある priceProcessor サービスから返される、価格の見積もりデータが保持されます。
availQuote には、ビジネス プロセスの For Each ループにある availProcessor サービスから返される、在庫の見積もりデータが保持されます。
taxRate は、taxCalculation サービスからビジネス プロセスに返された、出荷先に基づく消費税率を保持します。
次の図に示すように、[コントロールが予期する値] フィールドに、MyTutorialJoin コントロールの myJoin()
メソッドで予期されるデータ型が表示されます。
[データの受信] タブの [割り当てる変数を選択します] フィールドにデフォルトの変数 Quote が表示されます。データ型は myJoin
() メソッドの対象パラメータで想定されているデータ型と一致します。次の図に示すように、[コントロールが返す値] フィールドに、myJoin
() メソッドによって返されたデータ型 QuoteDocument が表示されます。
このチュートリアルでは、クエリの実行対象となる XML データを入力しました。実行時に、ビジネス プロセスは XML データを構築し、それをこのチュートリアルで構築されたクエリに渡します。ビジネス プロセスを実行して、クエリを呼び出すには、『チュートリアル : 初めてのビジネス プロセス設計』にある、「手順 12 : RequestQuote ビジネス プロセスの実行」の手順に従います。
![]() ![]() ![]() |