この章では、BPELプロセス・サービス・コンポーネントでのXMLデータの操作方法について説明します。この章では様々な例を提供します。変数、シーケンスおよび配列の使用方法とXPath式の使用方法、数学的計算などのタスクの実行方法に関するトピックが含まれています。 サポートされる仕様について概要を把握できる例を中心に説明しています。
項目は次のとおりです。
注意: この章の大部分の例では、関連するメッセージ・タイプを定義するWSDLファイルは、RPC形式ではなくドキュメント・リテラル形式であると想定しています。RPC形式のWSDL定義の場合、XPath問合せ文字列の構成方法に違いがあります。 RPCのWSDLファイルで定義されたタイプを使用する場合は、第7.18項「ドキュメント形式とRPC形式のWSDLファイルの違いの理解」を参照してください。 |
この項では、BPELプロセスでのXMLデータの使用について概要を説明します。
BPELプロセス・サービス・コンポーネントでは、ほとんどのデータがXML形式で記述されます。このようなデータには、BPELプロセス・サービス・コンポーネントがやり取りするメッセージ、外部サービスと交換されるメッセージおよびプロセスで使用されるローカル変数も含まれます。これらのメッセージおよび変数のタイプは、通常はフローのWSDL(Web Services Description Language)ファイル、起動するサービスのWSDLファイルまたはこれらのWSDLファイルで参照されるXSDファイル内に、XMLスキーマで定義します。このため、BPEL内のほとんどの変数がXMLデータであり、どのBPELプロセス・サービス・コンポーネントでも、コードの大半をこれらのXML変数の操作に使用します。このような操作の代表例には、様々なサービスに必要なデータ表現のトランスフォーメーションの実行、およびデータのローカル操作(複数のサービスを起動して得た結果を連結するなど)があります。
BPELでは、サービス・データ・オブジェクト(SDO)変数もサポートしています。この変数は、XML形式ではなく、メモリー構造形式です。
BPELのデータ操作は、XPath標準に基づくassignアクティビティが開始点になります。 このタイプの操作では多くの場合、XPath問合せ、式および関数が使用されます。また、XQuery、XSLTまたはJavaを必要とするさらに高度な方法も使用できます(通常は、より複雑なデータ・トランスフォーメーションや操作を実行する場合)。
この項では、BPELでのXMLデータの操作方法について一般的な概要を示します。様々な組合せに使用される主要なビルディング・ブロックの概要と例を示します。この章の残りの各項では、特定のタスクを実行するためにこれらのビルディング・ブロックを適用する方法も説明します。assign
アクティビティを使用すると、1つのXML変数から別のXML変数にデータをコピーしたり、式の値を計算して変数に格納できます。アクティビティ内のコピー要素は、割当てのソースとターゲット(コピー元とコピー先)を指定します。これらのソースとターゲットは、互換性のあるタイプである必要があります。 例7-1は、『Business Process Execution Language for Web Services Specification』に記載されている正式な構文を示しています。
例7-1 assignアクティビティ
<assign standard-attributes> standard-elements <copy> from-spec to-spec </copy> </assign>
この構文は、その仕様で詳細に説明されています。 通常、from-spec
およびto-spec
には、例7-2に示すように、変数または変数パートを指定します。
例7-2 from-spec属性とto-spec属性
<assign> <copy> <from variable="c1" part="address"/> <to variable="c3"/> </copy> </assign>
Oracle JDeveloperを使用する場合は、「From」セクションと「To」セクションを備えた「コピー操作」ダイアログでassignアクティビティの詳細を指定します。これにより、前述のBPELソース・コードの構文が反映されます。
XPath標準は、assignアクティビティで主要な役割を果たします。概要として簡単な例を示します。その他のコンテキストでの例と説明は、後続の各項で示します。
XPath問合せ
XPath問合せは、ソースまたはターゲットの変数パート内のフィールドを選択します。from
句またはto
句には、値がXPath問合せ文字列であるquery属性を含めることができます。 例7-3に例を示します。
query属性の値は、ただ1つのノードを選択するロケーション・パスである必要があります。query属性およびXPath標準の構文の詳細は、それぞれ『Business Process Execution Language for Web Services Specification』(第14.3項)、および『XML Path Language (XPath) Specification』を参照してください。
XPath式
XPath式(from
句のexpression
属性で指定)を使用して、変数に格納する値を指定します。次に例を示します。
<from expression="100"/>
式には一般的な式(つまり、任意のXPath値のタイプに評価されるXPath式)を指定できます。 同様に、式属性の値がコピー操作内のfrom
句で使用される場合、式属性の値は必ず1つのノードまたは1つのオブジェクトのみを返す必要があります。XPath式の詳細は、『XML Path Language (XPath) Specification』の第9.1.4項を参照してください。
XPath式内では、次の種類の関数をコールできます。
コアXPath関数
XPathでは、文字列操作関数(concat
など)や数値関数(sum
など)を含む多数の組込み関数がサポートされています。
<from expression="concat('string one', 'string two')"/>
XPath標準に組み込まれている関数の完全なリストは、『XML Path Language (XPath) Specification』の第4項を参照してください。
BPEL XPath拡張関数
BPELはいくつかの拡張関数をコアXPath関数に追加し、これによりXPath式がプロセスからの情報にアクセスできます。拡張関数は、標準BPELネームスペースhttp://schemas.xmlsoap.org/ws/2003/03/business-process/
で定義され、接頭辞bpws
:によって指定されます。
<from expression= "bpws:getVariableData('input', 'payload', '/p:value') + 1"/>
詳細は、『Business Process Execution Language for Web Services Specification』の第9.1項および第14.1項を参照してください。
Oracle BPEL XPath拡張関数
Oracleには、新しい関数を追加するためにBPELおよびXPath標準に組み込まれた機能を使用する、その他のXPath関数が用意されています。
これらの関数は、ネームスペースhttp://schemas.oracle.com/xpath/extension
で定義され、接頭辞ora:
によって指定されます。
カスタム関数
Oracle BPEL Process Managerの関数は、bpel-xpath-functions-config.xml
に定義され、orabpel.jar
ファイルに格納されます。 詳細は、B.7項「ユーザー定義XPath拡張関数の作成」および『Oracle Fusion Middleware Oracle SOA Suite管理者ガイド』を参照してください。
高度なデータ操作をBPELのassignアクティビティやコアXPath関数で実行するのは困難な場合があります。 しかし、複雑なデータ操作やデータ・トランスフォーメーションは、XSLT、Java、またはassignアクティビティのbpelx
操作(第7.14項「bpelx拡張要素を使用したXMLデータの操作」を参照)を使用したり、Webサービスとして実行することができます。XSLTのトランスフォーメーションについては、これらを実行するXPath関数がOracle BPEL Process Managerに用意されています。
XPathおよびXQueryトランスフォメーション・コードの例の詳細は、第45章「XSLTマッパーを使用したトランスフォーメーションの作成」を参照してください。
注意: assignアクティビティ経由で大きいスキーマが渡されると、「コピー操作」ダイアログの「From」セクションまたは「To」セクションでペイロードを右クリックして「すべて開く」を選択した場合に、Oracle JDeveloperが停止したり、メモリー不足になる可能性があります。 回避策として、ペイロード要素は手動で開いてください。 |
エンティティ変数を使用して、基礎となるデータ・プロバイダ・サービスがBPELデータ操作を実行するように指定できます。 データ・プロバイダ・サービスはデータ・ストア内でデータ操作をバックグラウンドで実行しますが、Oracle SOA Suiteが提供する他のデータ・ストア関連の機能(たとえば、データベース・アダプタ)を使用しません。 これにより、Oracle SOA Suiteの実行時パフォーマンスが向上し、コンパイルおよび実行時に、基礎となるデータ・プロバイダ・サービスのネイティブ機能が組み込まれます。
このリリースでは、エンティティ変数は、SDOベースのデータを使用してOracle Application Development Framework(ADF)Business Componentデータ・プロバイダ・サービスと一緒に使用できます。
以前のリリースでは、BPELビジネス・プロセス内で交換された変数およびメッセージは、XML構造に組み込まれる分離されたペイロード(Webサービスから返されるデータのスナップショット)でした。ある場合では、ユーザーにはこの構成要素タイプが必要でした。別の場合では、この構成要素は難題でした。
エンティティ変数は、次のような以前のリリースの難題に対応しています。
拡張データ変換
基礎となるデータがXML形式でない場合は、データ変換(デリミタ付きテキストからXMLへの変換など)が必要でした。基礎となるデータのサイズが大きい場合、処理はパフォーマンスに影響を与える場合がありました。
失効したスナップショット・データ
(WSDLメッセージを含めて)BPEL内の変数は分離されたペイロードでした。これが必要な場合もありました。別の場合では、Oracle BPEL Process Managerの外部にある他のアプリケーションによって変数が最新データに変更されて表示されることが必要でした。つまり、分離されたデータ・モデルでは、すべてのニーズを満たさない失効したデータ・セットが提供されていました。また、スナップショットによってデータが重複するため、データ・サイズが大きい場合はパフォーマンスに影響を与えていました。
ネイティブ・データ動作の損失
一部のデータ変換の実装には、XMLスキーマの範囲外のデータ構造の適用またはビジネス・データ・ロジックが必要でした。たとえば、開始日は終了日より前である必要があります。変数が分離されたペイロードの場合は、関連するWebサービスの起動中にのみ検証が実行されました。特定の操作後(ただしWebサービスの起動前)に、特別なビジネス・データ・ロジックの必要に応じた実行が推奨される場合がありました。
このリリースでこれらの難題に対応するには、変数宣言時にエンティティ変数を作成します。エンティティ変数は、バックグラウンドで様々なデータ・プロバイダ・サービス・テクノロジにアクセスし、プラグインするためのデータ・ハンドルとして機能します。コンパイルおよび実行時に、Oracle BPEL Process Managerは基礎となるデータ・プロバイダ・サービスにデータ操作を委任します。
表7-1では、以前のリリース(例としてデータベース・アダプタを使用)と、エンティティ変数を使用するリリース11gで、データ変換がどのように実行されるかを説明します。
表7-1 以前および現在のリリースでのデータ操作機能
10.1.xリリース | エンティティ変数を使用する場合の11gリリース |
---|---|
データを明示的にロードして保存するようなデータ操作は、Oracle BPEL Process Managerのデータベース・アダプタにより実行されていました。すべてのデータ(たとえば、注文書)はデータベースのデハイドレーション・ストアに保存されていました。 |
データをロードして保存するようなデータ操作は、データ・プロバイダ・サービス(Oracle ADF Business Componentアプリケーション)により自動的に実行され、サービスを起動するコードを記述する必要はありません。 Oracle BPEL Process Managerは、注文書データを指し示すキー(たとえば、注文書ID(POID))を格納します。 Oracle BPEL Process Managerは、データへのアクセスがリクエストされたときにこのキーをフェッチします(bind entityアクティビティが実行します)。 キーを使用してデータをバインドするように明示的にリクエストする必要があります。データ・プロバイダ・サービスは、すべてのデータ変更をデハイドレーション・ストア・データベースとは異なるデータベースに格納します。これによりデータは重複しません。 |
変数内のデータはドキュメント・オブジェクト・モデル(DOM)形式でした。 |
変数内のデータはSDO形式であり、DOMより簡単に変換処理できます。特に、データ・プロバイダ・サービスがSDO形式に対応している場合は簡単です。 |
注意: 現在は、BPELプロセス・サービス・コンポーネントのみがSDO形式の変数を使用できます。 コンポジット・アプリケーションに、SDOベースのJavaバインディング・コンポーネント参照と接続されたOracle Mediatorサービス・コンポーネントがある場合、変数のデータ形式のデフォルトはDOMとなります。 さらに、表7-1で説明したリリース10.1.xの機能は、リリース11gでもサポートされています。 |
エンティティ変数の使用については、次のドキュメントを参照してください。
bpel-203-EntityVariableToADFBC
:
このサンプルでは、SDOインタフェースを使用してOracle ADF BCサービスにバインドされているエンティティ変数を使用します。 これにより、標準的なBPEL変数のように動作する変数がBPELプロセスに提供されます。 ただし、データはBPELプロセス(この場合は、Oracle ADF BCコンポーネント)の外部に保持されます。 大きいペイロード・データを順に渡すのではなく、1箇所に配置されます。 データを読み取って更新するために、参照キーが順に渡されます。
bpel-204-EntityVariableToBPELBackedSDO
:
このサンプルは、Oracle ADF BC SDOインタフェースをどのように使用できるかを示します。ただし、バック・エンドはOracle ADF BCアプリケーション以外で実装されます。 このサンプルでは、バック・エンドはBPELプロセスを使用して実装されています。
これらのサンプルの詳細は、次のURLにアクセスしてください。
http://www.oracle.com/technology/sample_code/products/bpel
『Oracle Fusion Middleware Oracle SOA Suiteアプリケーションの作成および実行のためのチュートリアル』(エンティティ変数の作成方法の説明)
この項では、Oracle JDeveloperでエンティティ変数とバインディング・キーを作成する方法について説明します。
Oracle BPEL Process Managerの以前のリリースでは、すべての変数データはDOM形式でした。リリース11gでは、SDO形式の変数データもサポートされています。BPELプロセス・サービス・コンポーネントのDOMおよびSDO変数は、暗黙的に必要な形式に変換されます。たとえば、DOMベースの変数を使用するOracle BPELサービス・コンポーネントは、これらの変数を必要に応じてassignアクティビティでSDOベースの変数に自動的に変換し、逆の場合も同様に変換します。いずれのタイプの形式もXSDスキーマ・ファイルで定義されています。ユーザー操作は不要です。
エンティティ変数は、SDO形式のデータもサポートしています。ただし、DOM変数やSDO変数とは異なり、SDOベースのデータを持つエンティティ変数を使用すると、データ(たとえば、注文書)に一意のキー値をバインドできます。そのキーのみが、デハイドレーション・ストアに格納されます。変換が必要なデータは、Oracle ADF Business Componentアプリケーションのサービスと一緒に格納されます。キーはサービス内に格納されるデータを指し示します。データが必要な場合はデータ・プロバイダ・サービスからフェッチされ、メモリーに配置されます。 プロセスは、bind entityアクティビティとデハイドレーション・ストアの2つの場所で発生します。 たとえば、Oracle BPEL Process Managerがリハイドレートする場合は、エンティティ変数のキーのみが格納され、ウェイクアップ時には、暗黙的なバインドが行われて現在のデータが取得されます。
SDOバインディング・コンポーネント・サービスは、図7-1に示すように、コンポジット・アプリケーションへのエントリ・ポイントを外部に提供します。
SOAコンポジット・エディタおよびOracle BPELデザイナを使用して次のタスクを実行します。
SDOバインディング・コンポーネント・サービスとBPELプロセス・サービス・コンポーネントをコンポジット・アプリケーションに定義します。
SDOサービスとBPELプロセス・サービス・コンポーネントを接続(ワイヤ)します。
BPELプロセス・サービス・コンポーネントの詳細を定義します。
SOAコンポジット・エディタの使用方法の詳細は、第4章「SOAコンポジット・エディタの機能の概要」を参照してください。
図7-2に示すように、SDOバインディング・コンポーネント参照を使用すると、コンポジット・アプリケーションからOracle ADF Business Componentアプリケーションの外部のパートナにメッセージを送信できます。
Oracle ADF Business Componentアプリケーションが外部へのパートナ・リンクの場合、SOAコンポジット・エディタには、アウトバウンド通信を作成するためにコンポジット・アプリケーションにドラッグするSDOバインディング・コンポーネント参照はありません。かわりに、コンポジット・アプリケーションおよびOracle ADF Business Componentアプリケーションの間に次の通信が発生します。
Oracle ADF Business Componentアプリケーションはデプロイされ、自動的にサービス・インフラストラクチャのSDOサービスとして登録されます。
Oracle JDeveloperを使用してADF-BCサービスとしてこのアプリケーションを参照および検索し、パートナ・リンク接続を作成します。
Oracle ADF Business Componentアプリケーション・サービスが検出された場合、composite.xml
ファイルは、参照の詳細(binding.adf
プロパティ)で自動的に更新されます。
ここでは、Oracle ADF Business Componentアプリケーションのために、エンティティ変数を作成し、パートナ・リンクを選択します。 次の例は、WebLogic Fusion Order Demoアプリケーションで、Oracle ADF Business Componentデータ・プロバイダ・サービスの注文データを指し示すために、bind entityアクティビティを使用して、OrderProcessor BPELプロセス・サービス・コンポーネントが注文IDを受け取る方法を示しています。
詳細は、『Oracle Fusion Middleware Oracle SOA Suiteアプリケーションの作成および実行のためのチュートリアル』を参照してください。
エンティテイ変数を作成し、パートナ・リンクを選択する手順は、次のとおりです。
Oracle JDeveloperで、BPELプロセス・サービス・コンポーネントの「構造」ウィンドウに移動します。
「変数」フォルダを右クリックし、「すべての子ノードを開く」を選択します。
2番目の「変数」フォルダで、右クリックして「変数の作成」を選択します。
「変数の作成」ダイアログが表示されます。
「名前」フィールドに、名前を入力します。
「エンティティ変数」チェック・ボックスを選択し、「パートナ・リンク」フィールドの右側の「検索」アイコンを選択します。
「パートナ・リンク・チューザ」ダイアログに、使用可能なサービス(「ADF-BCサービス」というSDOサービスを含む)のリストが表示されます。
Oracle ADF Business Componentアプリケーションのためのサービスを参照し、選択します。
「OK」をクリックし、「パートナ・リンク・チューザ」ダイアログと「変数の作成」ダイアログを閉じます。
「変数の作成」ダイアログの外観を次に示します。
ここでは、Oracle ADF Business Componentデータ・プロバイダ・サービスの注文データを指し示すキーを作成します。
バインディング・キーを作成する手順は、次のとおりです。
bind entityアクティビティを、BPELプロセス・サービス・コンポーネントにドラッグします。
「Bind Entity」ダイアログが表示されます。
「名前」フィールドに、名前を入力します。
「エンティティ変数」フィールドの右側の「検索」アイコンをクリックします。
「変数チューザ」ダイアログが表示されます。
第7.2.1.3項「エンティティ変数の作成とパートナ・リンクの選択」で作成したエンティティ変数を選択し、「OK」をクリックします。
「一意キー」セクションで、「追加」アイコンをクリックします。
「キーの指定」ダイアログが表示されます。 このダイアログを使用して、Oracle ADF Business Componentデータ・プロバイダ・サービスから注文IDを取得するためのキーを作成します。
表7-2に記載されている詳細を入力し、バインディング・キーを定義します。
表7-2 「キーの指定」ダイアログのフィールドと値
フィールド | 値 |
---|---|
キー・ローカル・パート |
キーのローカル・パートを入力します。 |
キー・ネームスペースURI |
キーに対するネームスペースURIを入力します。 |
キー値 |
キー値式を入力します。この式はキーのタイプと一致する必要があります。次に、POIDキーに対する式値キーの例を示します。
エンティティ変数に対するPOIDキーは、通常、別のメッセージから取得されます。 POIDキーのタイプが整数で、式の結果が |
図7-4に、完成した「キーの指定」ダイアログを示します。
「OK」をクリックして「キーの指定」ダイアログを閉じます。
次のように、「一意キー」の表に名前/値ペアが表示されます。これで、設計は完了します。
「OK」をクリックして「Bind Entity」ダイアログを閉じます。
実行時にbind entityアクティビティが実行されると、エンティティ変数を使用する準備が整います。
SDOの使用方法の詳細は、『Oracle Fusion Middleware Oracle Application Development Framework Fusion開発者ガイド』を参照してください。 このガイドには、アプリケーション・モジュールをWebサービスとして公開する方法や、表示データ・オブジェクトの行をSDOとして公開する方法が記載されています。 アプリケーション・モジュールは、ビジネス・ロジックを関連する一連のビジネス機能としてカプセル化するADFフレームワーク・コンポーネントです。
スタンドアロンSDOベースの変数は、通常のBPEL XML-DOMベースの変数と類似しています。 主な違いは、基礎となるデータ形式がDOMベースではなくSDOベースであることです。 したがって、SDOベースの変数は、Java APIアクセス、簡単に使用できる最新のAPI、変更内容の要約など、様々なSDO機能を使用できます。 ただし、SDOを使用する場合は、XML-DOMベースの変数を使用する場合にはない複数の制限も適用されます。 最も顕著な制限は、SDOがXPath式の小さいサブセットのみをサポートしていることです。
SDOベースの変数を宣言するための構文は、BPEL変数を宣言する構文と類似しています。 例7-4に詳細を示します。
例7-4 SDOベースの変数の宣言
<variable name="deptVar_s" element="hrtypes:dept" /> <variable name="deptVar_v" element="hrtypes:dept" bpelx:sdoCapable="false" />
自動検出を無効にする場合は、bpelx:sdoCapable="true|false"
スイッチを使用します。 たとえば、例7-4の変数deptVar_v
は通常のDOMベースの変数です。 例7-4にスキーマの例を示します。
例7-5 XSDのサンプル
<xsd:element name="dept" type="Dept"/> <xsd:complexType name="Dept" sdoJava:instanceClass="sdo.sample.service.types.Dept"> <xsd:annotation> <xsd:appinfo source="Key" xmlns="http://xmlns.oracle.com/bc4j/service/metadata/"> <key> <attribute>Deptno</attribute> </key> <fetchMode>minimal</fetchMode> </xsd:appinfo> </xsd:annotation> <xsd:sequence> <xsd:element name="Deptno" type="xsd:integer" minOccurs="0"/> <xsd:element name="Dname" type="xsd:string" minOccurs="0" nillable="true"/> <xsd:element name="Loc" type="xsd:string" minOccurs="0" nillable="true"/> <xsd:element name="Emp" type="Emp" minOccurs="0" maxOccurs="unbounded" nillable="true"/> </xsd:sequence> </xsd:complexType>
Oracle BPEL Process Managerでは、DOMとSDOの2つのデータ形式をサポートしています。 同じビジネス・プロセス内で、さらに同じ式の中で、DOMベースの変数とSDOベースの変数の使用を切り替えることができます。 Oracle BPEL Process Managerのデータ・フレームワークは、DOM形式とSDO形式を自動的に変換します。
Oracle BPEL Process Managerでは、エンティティ変数のXPathリライト機能を使用することで、基本的なSDO仕様ではサポートされない複数のXPath機能(変数の参照、関数コールなど)を使用できます。 一方で、SDOベースの変数を使用するXPathには、別の制限があります(and
、or
およびnot
がサポートされないなど)。
例7-6に、XMLからSDOに変換する簡単な例を示します。
例7-6 XMLからSDOへの変換
<assign> <copy> <from> <ns0:dept xmlns:ns0="http://sdo.sample.service/types/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <ns0:Deptno>10</ns0:Deptno> <ns0:Dname>ACCOUNTING</ns0:Dname> <ns0:Loc>NEW YORK</ns0:Loc> <ns0:Emp> <ns0:Empno>7782</ns0:Empno> <ns0:Ename>CLARK</ns0:Ename> <ns0:Job>MANAGER</ns0:Job> <ns0:Mgr>7839</ns0:Mgr> <ns0:Hiredate>1981-06-09</ns0:Hiredate> <ns0:Sal>2450</ns0:Sal> <ns0:Deptno>10</ns0:Deptno> </ns0:Emp> <ns0:Emp> <ns0:Empno>7839</ns0:Empno> <ns0:Ename>KING</ns0:Ename> <ns0:Job>PRESIDENT</ns0:Job> <ns0:Hiredate>1981-11-17</ns0:Hiredate> <ns0:Sal>5000</ns0:Sal> <ns0:Deptno>10</ns0:Deptno> </ns0:Emp> <ns0:Emp> <ns0:Empno>7934</ns0:Empno> <ns0:Ename>MILLER</ns0:Ename> <ns0:Job>CLERK</ns0:Job> <ns0:Mgr>7782</ns0:Mgr> <ns0:Hiredate>1982-01-23</ns0:Hiredate> <ns0:Sal>1300</ns0:Sal> <ns0:Deptno>10</ns0:Deptno> </ns0:Emp> </ns0:dept> </from> <to variable="deptVar_s" /> </copy> </assign>
例7-7に、SDO変数のXPath式からDOM変数にコピーする例を示します。
例7-7 SDO変数のXPath式からDOM変数へのコピー
<assign> <!-- copy from an XPath expression of an SDO variable to DOM variable --> <copy> <from expression="$deptVar_s/hrtypes:Emp[2]" /> <to variable="empVar_v" /> </copy> <!-- copy from an XPath expression of an DOM variable to SDO variable --> <copy> <from expression="$deptVar_v/hrtypes:Emp[2]" /> <to variable="empVar_s" /> </copy> <!-- insert a DOM based data into an SDO variable --> <bpelx:insertAfter> <bpelx:from variable="empVar_v" /> <bpelx:to variable="deptVar_s" query="hrtypes:Emp" /> </bpelx:insertAfter> <!-- insert a SDO based data into an SDO variable at particular location, no XML conversion is needed --> <bpelx:insertBefore> <bpelx:from expression="$deptVar_s/hrtypes:Emp[hrtypes:Sal = 1300]" /> <bpelx:to variable="deptVar_s" query="hrtypes:Emp[6]" /> </bpelx:insertBefore> </assign>
例7-8に、SDOデータの一部を削除する例を示します。
例7-8
<assign> <bpelx:remove> <bpelx:target variable="deptVar_s" query="hrtypes:Emp[2]" /> </bpelx:remove> </assign>
注意: SDOベースの変数に対するbpelx:append 操作は、次の理由によりサポートされていません。
|
BPELでは、リテラルXMLを変数に割り当てる方法が役立つことがよくあります。たとえば、動的データを変数に対するXMLデータ・コンテンツ内の特定のフィールドにコピーする前に、変数を初期化する場合などです。また、XMLデータ値をプロセスにハード・コーディングするときのテストにも役立ちます。
変数間のコピーでは、1つの変数(またはパート)から互換性のあるタイプの別の変数に直接コピーします。どちらの変数でも特定のフィールドを指定する必要はありません。つまり、XPath問合せを指定する必要はありません。
例7-10は、2つの割当ての実行を示しています。最初に同じタイプの2つの変数の間でコピーを実行し、次に変数パートをそのパートと同じタイプの別の変数の変数パートにコピーします。
例7-10 変数間のコピー
<assign> <copy> <from variable="c1"/> <to variable="c2"/> </copy> <copy> <from variable="c1" part = "address"/> <to variable="c3"/> </copy> </assign>
例7-11に示すように、BPELファイルは変数を定義します。
例7-11 変数定義
<variable name="c1" messageType="x:person"/> <variable name="c2" messageType="x:person"/> <variable name="c3" element="y:address"/>
例7-12に示すように、WSDLファイルはperson
メッセージ・タイプを定義します。
例7-12 メッセージ・タイプ定義
<message name="person" xmlns:x="http://tempuri.org/bpws/example"> <part name="full-name" type="xsd:string"/> <part name="address" element="x:address"/> </message>
このコーディング例の詳細は、『Business Process Execution Language for Web Services Specification』の第9.3.2項を参照してください。
ほとんどのWSDLファイルやXSDファイルに定義のタイプが存在する場合は、要素およびメッセージ・タイプに基づいて変数パート内のコピー元またはコピー先フィールドのレベルに移動する必要があります。 そこで、XMLスキーマの複合型を順に使用します。 このアクションを実行するには、assignアクティビティのfrom
句またはto
句にXPath問合せを指定します。
例7-13では、ssn
フィールドはCreditFlow
プロセスの入力メッセージから信用格付けサービスの入力メッセージのssn
フィールドにコピーされます。
例7-13 レベルをコピーするフィールド
<assign> <copy> <from variable="input" part="payload" query="/tns:CreditFlowRequest/tns:ssn"/> <to variable="crInput" part="payload" query="/tns:ssn"/> </copy> </assign>
例7-14は、この割当てに必要なメッセージ・タイプベースの変数をBPELファイルに定義する方法を示しています。
例7-14 BPELファイル定義 - メッセージ・タイプベースの変数
<variable name="input" messageType="tns:CreditFlowRequestMessage"/> <variable name="crInput" messageType="services:CreditRatingServiceRequestMessage"/>
crInput
変数は、信用格付けサービスへの入力メッセージとして使用されます。
そのメッセージ・タイプCreditFlowRequestMessage
は、例7-15に示すように、CreditFlowService.wsdl
ファイルで定義されます。
例7-15 CreditFlowRequestMessage定義
<message name="CreditFlowRequestMessage"> <part name="payload" element="tns:CreditFlowRequest"/> </message>
CreditFlowRequest
は、ssn
という名前のフィールドで定義されます。 メッセージ・タイプCreditRatingServiceRequestMessage
は、例7-16に示すように、CreditRatingService.wsdl
ファイルで定義されます。
例7-16 CreditRatingServiceRequestMessage定義
<message name="CreditRatingServiceRequestMessage"> <part name="payload" element="tns:ssn"/> </message>
BPELプロセスでは、要素ベースの変数も使用できます。 例7-17では、autoloan
フィールドは融資申請プロセスの入力メッセージからWebサービスの入力メッセージのcustomer
フィールドにコピーされます。
例7-17 レベルをコピーするフィールド
<assign> <copy> <from variable="input" part="payload" query="/tns:invalidLoanApplication/autoloan: application/autoloan:customer"/> <to variable="customer"/> </copy> </assign>
例7-18は、割当てに必要な要素ベースの変数をBPELファイルに定義する方法を示しています。
第7.8.1項「XPath標準による数学的計算の使用方法」の数値を増分する数式のような簡単な数式を使用できます。
例7-20では、BPEL XPath関数getVariableData
により、増分した値が取得されます。getVariableData
への引数は、from
句のvariable、partおよびquery属性と同じです(オプションの最後の2つの引数を含む)。
例7-20 XPath関数getVariableDataによる値の取得
<assign> <copy> <from expression="bpws:getVariableData('input', 'payload', '/p:value') + 1"/> <to variable="output" part="payload" query="/p:result"/> </copy> </assign>
また、例7-21に示すように、$variable
構文を使用することもできます。
文字列リテラルをBPEL内の変数に割り当てることができます。
例7-22のコードは、文字列リテラル'GE'
から評価される式を、指定された変数パート内のsymbolフィールドにコピーしています(二重引用符および一重引用符を使用していることに注意してください)。
1つの文字列変数(または変数パート、フィールド)の値を別の文字列変数にコピーするのではなく、いくつかの文字列を連結するなどの文字列操作を最初に実行できます。
連結はconcat
という名前のコアXPath関数で実行されます。また、連結に必要な変数値は、BPEL XPath関数getVariableData
によって取得されます。 例7-23では、getVariableData
は、input
変数のpayload
パートからname
フィールドの値をフェッチします。次に、文字リテラル'Hello '
が、この値の先頭に連結されます。
例7-23 XPath関数getVariableDataによるデータのフェッチ
<assign> <!-- copy from XPath expression to the variable --> <copy> <from expression="concat('Hello ', bpws:getVariableData('input', 'payload', '/p:name'))"/> <to variable="output" part="payload" query="/p:result/p:message"/> </copy> </assign>
XPathで使用可能なその他の文字操作関数は、『XML Path Language (XPath) Specification』の第4.2項を参照してください。
XPathブール関数を使用してブール値を割り当てることができます。
例7-24は、ブール値を割り当てる例を示しています。from
句のXPath式は、XPathブール関数true
のコールであり、指定されたapprovedフィールドがtrue
に設定されます。関数false
も使用できます。
例7-24 ブール値の割当て
<assign> <!-- copy from boolean expression function to the variable --> <copy> <from expression="true()"/> <to variable="output" part="payload" query="/result/approved"/> </copy> </assign>
XPath仕様では、ブール定数値を返すメソッドとして"true()"
および"false()"
関数を使用するように推奨しています。
かわりに"boolean(true)"
または"boolean(false)"
を使用すると、ブール関数内のtrue
またはfalse
はtrue
またはfalse
定数ではなく相対要素ステップと解釈されます。 現行のXPathコンテキスト・ノードでtrue
という子ノードの選択が試行されます。ほとんどの場合、true
ノードは存在しません。したがって、空の結果ノードセットが返され、それがXPath 1.0のboolean()
関数によりfalseの結果に変換されます。この結果は混同される可能性があります。
Oracle BPEL XPath関数のgetCurrentDate
、getCurrentTime
またはgetCurrentDateTime
を使用して、日付または時刻フィールドの現在値を割り当てることができます。さらに、日時の値が標準XSD形式の場合は、Oracle BPEL XPath関数formatDate
をコールして、出力用により適切な文字に変換できます。
詳細は、『Business Process Execution Language for Web Services Specification』の第9.1.2項を参照してください。
例7-25は、関数getCurrentDate
を使用する例を示しています。
例7-25 日付または時刻の割当て
<!-- execute the XPath extension function getCurrentDate() --> <assign> <copy> <from expression="xpath20:getCurrentDate()"/> <to variable="output" part="payload" query="/invoice/invoiceDate"/> </copy> </assign>
例7-26では、XSD形式で指定された日時の値をformatDate
関数が文字列'Jun 10, 2005'
に変換し、文字列フィールドformattedDate
に割り当てています。
XML属性として定義されている要素は相互にコピーできます。XPath問合せ構文では、@
記号は子要素のかわりに属性を参照します。
例7-27のコードは、このXMLデータからcustId
属性をフェッチしてコピーしています。
例7-27 custId属性のフェッチ操作とコピー操作
<invalidLoanApplication xmlns="http://samples.otn.com"> <application xmlns = "http://samples.otn.com/XPath/autoloan"> <customer custId = "111" > <name> Mike Olive </name> ... </customer> ... </application> </invalidLoanApplication>
例7-28のコードは、customerフィールドのcustId
属性を選択し、変数custId
に割り当てています。
例7-28 custId属性の選択操作と割当て操作
<assign> <!-- get the custId attribute and assign to variable custId --> <copy> <from variable="input" part="payload" query="/tns:invalidLoanApplication/autoloan:application /autoloan:customer/@custId"/> <to variable="custId"/> </copy> </assign>
この例のネームスペース接頭辞は必須ではありません。例7-29に示すように、WSDLファイルには、custId
が属性として定義される型を持つように顧客を定義します。
assignアクティビティでXMLデータに対して各種操作を実行できます。 この項に記述されているbpelx
拡張タイプにより、この機能が提供されます。
注意: bpelx:append 拡張要素では、SDO変数の使用はサポートされていません。エラーが発生します。 |
assignアクティビティでbpelx:append
拡張要素を使用すると、BPELプロセス・サービス・コンポーネントは1つの変数、式またはXMLフラグメントのコンテンツを別の変数のコンテンツに追加できます。 例7-30に例を示します。
例7-30 bpelx:append拡張要素
<bpel:assign> <bpelx:append> <bpelx:from ... /> <bpelx:to ... /> </bpelx:append> </bpel:assign>
bpelx:append
内のfrom-spec
問合せでは、0(ゼロ)個以上のノードが取得されます。ノード・リストは、to-spec
問合せで指定したターゲット・ノードに子ノードとして追加されます。
to-spec
問合せでは、単一L-Value要素ノードを1つ取得する必要があります。それ以外の場合は、bpel:selectionFailure
フォルトが生成されます。to-spec
問合せではパートナ・リンクを参照できません。
例7-31では、1つのBOMの複数のb:part
を連結BOMのb:
parts
に追加することで、複数の部品表を1つの部品表に連結しています。
注意: bpelx:insertBefore 拡張要素ではSDO変数を使用できますが、ターゲットは、コピーされたデータの移動先の変数属性にする必要があります。 |
assignアクティビティでbpelx:insertBefore
拡張要素を使用すると、BPELプロセス・サービス・コンポーネントは1つの変数、式またはXMLフラグメントのコンテンツを別の変数のコンテンツの前に挿入できます。 例7-32に例を示します。
例7-32 bpelx:insertBefore拡張要素
<bpel:assign> <bpelx:insertBefore> <bpelx:from ... /> <bpelx:to ... /> </bpelx:insertBefore> </bpel:assign>
bpelx:insertBefore
内のfrom-spec
問合せでは、0(ゼロ)個以上のノードが取得されます。ノード・リストは、to-spec
問合せで指定したターゲット・ノードに子ノードとして追加されます。
insertBefore
操作のto-spec
問合せは、1つ以上の単一L-Valueノードを指し示します。 複数のノードが返された場合は、最初のノードが参照ノードとして使用されます。参照ノードは要素ノードである必要があります。参照ノードの親も要素ノードである必要があります。それ以外の場合は、bpel:selectionFailure
フォルトが生成されます。from-spec
問合せの選択により生成されたノード・リストは、参照ノードの前に挿入されます。to-spec
問合せではパートナ・リンクを参照できません。
例7-33は、<insertBefore>
の実行前の構文を示しています。addrVar
の値は次のとおりです。
例7-34は、実行後の構文を示しています。
例7-34 実行後の構文
<bpel:assign>
<bpelx:insertBefore>
<bpelx:from>
<a:city>Redwood Shore></a:city>
</bpelx:from>
<bpelx:to "addrVar" query="/a:usAddress/a:state" />
</bpelx:insertBefore>
</bpel:assign>
例7-35は、addrVar
の値を示しています。
注意: bpelx:insertAfter 拡張要素ではSDO変数を使用できすが、ターゲットは、コピーされたデータの移動先の変数属性にする必要があります。 |
assignアクティビティでbpelx:insertAfter
拡張要素を使用すると、BPELプロセス・サービス・コンポーネントは1つの変数、式またはXMLフラグメントのコンテンツを別の変数のコンテンツの後に挿入できます。 例7-36に例を示します。
例7-36 bpelx:insertAfter拡張要素
<bpel:assign> <bpelx:insertAfter> <bpelx:from ... /> <bpelx:to ... /> </bpelx:insertAfter> </bpel:assign>
この操作は第7.14.2項「bpelx:insertBeforeの使用方法」で説明した機能に類似していますが、次の違いがあります。
to-spec
問合せで複数のL-Valueノードが返される場合は、最後のノードが参照ノードとして使用されます。
参照ノードの前にノードが挿入されるかわりに、参照ノードの後にソース・ノードが挿入されます。
この操作は、conditional-switch
+
(append
またはinsertBefore
)のマクロとみなすこともできます。
例7-37は、<insertAfter>
の実行前の構文を示しています。addrVar
の値は次のとおりです。
例7-37 実行前の構文
<a:usAddress> <a:addressLine>500 Oracle Parkway</a:addressLine> <a:state>CA</a:state> <a:zipcode>94065</a:zipcode> </a:usAddress>
例7-38は、実行後の構文を示しています。
例7-38 実行後の構文
<bpel:assign>
<bpelx:insertAfter>
<bpelx:from>
<a:addressLine>Mailstop 1op6</a:addressLine>
</bpelx:from>
<bpelx:to "addrVar" query="/a:usAddress/a:addressLine[1]" />
</bpelx:insertAfter>
</bpel:assign>
例7-39は、addrVar
の値を示しています。
例7-39 addrVarの値
<a:usAddress>
<a:addressLine>500 Oracle Parkway</a:addressLine>
<a:addressLine>Mailstop 1op6</a:addressLine>
<a:state>CA</a:state>
<a:zipcode>94065</a:zipcode>
</a:usAddress>
bpelx:insertAfter
内のfrom-spec
問合せでは、0(ゼロ)個以上のノードが取得されます。ノード・リストは、to-spec
問合せで指定したターゲット・ノードに子ノードとして追加されます。
assignアクティビティでbpelx:remove
拡張要素を使用すると、BPELプロセス・サービス・コンポーネントは変数を削除できます。 例7-40に例を示します。
例7-40 bpelx:remove拡張要素
<bpel:assign> <bpelx:remove> <bpelx:target variable="ncname" part="ncname"? query="xpath_str" /> </bpelx:append> </bpel:assign>
XPath式で指定したノード削除がサポートされます。XPath式では複数のノードを指定できますが、いずれもL-Valueである必要があります。この親からは、テキスト・ノード、属性ノードおよび要素ノードを削除できます。
XPath式では、1つ以上のノードを返すことができます。XPath式で0(ゼロ)個のノードが返される場合は、bpel:selectionFailure
フォルトが生成されます。
bpelx:target
の構文は、copy
操作のto-spec
に類似しており、そのサブセットです。
例7-41は、次の値を持つaddrVar
を示しています。
例7-41 addrVar
<a:usAddress> <a:addressLine>500 Oracle Parkway</a:addressLine> <a:addressLine>Mailstop 1op6</a:addressLine> <a:state>CA</a:state> <a:zipcode>94065</a:zipcode> </a:usAddress>
BPELプロセス・サービス・コンポーネント・ファイルで例7-42に示す構文を実行すると、2番目のアドレス行であるMailstop
が削除されます。
例7-42 2番目のアドレス行の削除
<bpel:assign>
<bpelx:remove>
<target variable="addrVar"
query="/a:usAddress/a:addressLine[2]" />
</bpelx:remove>
</bpel:assign>
BPELプロセス・サービス・コンポーネント・ファイルで例7-43に示す構文を実行すると、両方のアドレス行が削除されます。
assignアクティビティでbpelx:rename
拡張要素を使用すると、BPELプロセス・サービス・コンポーネントはXSDタイプ・キャストを使用して要素名を変更できます。 例7-44に例を示します。
例7-44 bpelx:rename拡張要素
<bpel:assign> <bpelx:rename elementTo="QName1"? typeCastTo="QName2"?> <bpelx:target variable="ncname" part="ncname"? query="xpath_str" /> </bpelx:rename> </bpel:assign>
bpelx:target
の構文は、copy
操作のto-spec
に類似しており、そのサブセットです。ターゲットはさらに1つの要素ノードのリストを返す必要があります。それ以外の場合は、bpel:selectionFailure
フォルトが生成されます。 from-spec
で指定した要素ノード名が、elementTo
属性で指定したQName
に変更されます。その要素ノードにxsi:type
属性が追加され、それらの要素がtypeCastTo
属性で指定したQName
タイプにキャストされます。
例7-45に示す従業員リストがあるとします。
例7-45 xsi:type属性
<e:empList> <e:emp> <e:firstName>John</e:firstName><e:lastName>Dole</e:lastName> <e:emp> <e:emp xsi:type="e:ManagerType"> <e:firstName>Jane</e:firstName><e:lastName>Dole</e:lastName> <e:approvalLimit>3000</e:approvalLimit> <e:managing /> <e:emp> <e:emp> <e:firstName>Peter</e:firstName><e:lastName>Smith</e:lastName> <e:emp> <e:emp> <e:firstName>Mary</e:firstName><e:lastName>Smith</e:lastName> <e:emp> </e:empList>
昇格の変更が、例7-46の従業員リストのPeter Smith
に適用されます。
例7-46 昇格変更の適用
<bpel:assign> <bpelx:rename typeCastTo="e:ManagerType"> <bpelx:target variable="empListVar" query="/e:empList/e:emp[./e:firstName='Peter' and ./e:lastName='Smith'" /> </bpelx:rename> </bpel:assign>
前述のキャスト(名前変更)の実行後は、例7-47に示すように、Peter Smith
にxsi:type
情報が追加され、データは次のようになります。
例7-47 データ出力
<e:empList>
<e:emp>
<e:firstName>John</e:firstName><e:lastName>Dole</e:lastName>
<e:emp>
<e:emp xsi:type="e:ManagerType">
<e:firstName>Jane</e:firstName><e:lastName>Dole</e:lastName>
<e:approvalLimit>3000</e:approvalLimit>
<e:managing />
<e:emp>
<e:emp xsi:type="e:ManagerType">
<e:firstName>Peter</e:firstName><e:lastName>Smith</e:lastName>
<e:emp>
<e:emp>
<e:firstName>Mary</e:firstName><e:lastName>Smith</e:lastName>
<e:emp>
</e:empList>
<approvalLimit>
および<managing>
がないため、Peter Smith
の従業員データは無効になっています。したがって、その情報を追加するために<append>
が使用されます。 例7-48に例を示します。
例7-48 append拡張要素を使用した情報の追加
<bpel:assign> <bpelx:rename typeCastTo="e:ManagerType"> <bpelx:target variable="empListVar" query="/e:empList/e:emp[./e:firstName='Peter' and ./e:lastName='Smith'" /> </bpelx:rename> <bpelx:append> <bpelx:from> <e:approvalLimit>2500</e:approvalLimit> <e:managing /> </bpelx:from> <bpelx:to variable="empListVar" query="/e:empList/e:emp[./e:firstName='Peter' and ./e:lastName='Smith'" /> </bpelx:append> </bpel:assign>
rename
およびappend
の両方を実行すると、対応するデータは例7-49のようになります。
assignアクティビティでbpelx:copyList
拡張要素を使用すると、BPELプロセス・サービス・コンポーネントは1つの変数、式またはXMLフラグメントのコンテンツに対して別の変数へのcopyList
操作を実行できます。 例7-50に例を示します。
例7-50 bpelx:copyList拡張要素
<bpel:assign> <bpelx:copyList> <bpelx:from ... /> <bpelx:to ... /> </bpelx:copyList> </bpel:assign>
from-spec
問合せでは、すべての属性ノードまたはすべての要素ノードのリストを取得できます。 to-spec
問合せでは、L-Valueノード(すべての属性ノードまたはすべての要素ノード)のリストを取得できます。
to-spec
問合せで返される要素ノードは、すべて同じ親要素を持つ必要があります。to-spec
問合せで要素ノードのリストが返される場合は、すべての要素ノードが連続している必要があります。
from-spec
問合せで属性ノードが返される場合、to-spec
問合せでは属性ノードが返される必要があります。同様に、from-spec
問合せで要素ノードが返される場合、to-spec
問合せでは要素ノードが返される必要があります。それ以外の場合は、bpws:mismatchedAssignmentFailure
フォルトがスローされます。
from-spec
問合せでは0(ゼロ)個のノードを返すことができますが、to-spec
問合せではノードを1個以上返す必要があります。from-spec
問合せで0(ゼロ)個のノードが返される場合、copyList
操作の効果はremove
操作と同様になります。
copylist
操作には、次の機能があります。
to-spec
問合せが指すノードがすべて削除されます。
to-spec
問合せで要素ノードのリストが返され、そのノードが削除された後に子ノードが残っている場合、from-spec
問合せで返されたノードは、to-spec
問合せで指定した最後の要素と同レベルの次の要素の前に挿入されます。残りの子ノードがない場合は、append
操作が実行されます。
to-spec
問合せで属性ノードのリストが返される場合は、その属性が親要素から削除されます。 次に、from-spec
問合せで返された属性が親要素に追加されます。
たとえば、例7-51に示すようなスキーマが定義されているとします。
例7-51 スキーマ
<schema attributeFormDefault="unqualified" elementFormDefault="qualified" targetNamespace="http://xmlns.oracle.com/Event_jws/Event/EventTest" xmlns="http://www.w3.org/2001/XMLSchema"> <element name="process"> <complexType> <sequence> <element name="payload" type="string" maxOccurs="unbounded"/> </sequence> </complexType> </element> <element name="processResponse"> <complexType> <sequence> <element name="payload" type="string" maxOccurs="unbounded"/> </sequence> </complexType> </element> </schema>
from
変数には、例7-52に示すコンテンツが含まれています。
例7-52 変数のコンテンツ
<ns1:process xmlns:ns1="http://xmlns.oracle.com/Event_jws/Event/EventTest"> <ns1: payload >a</ns1: payload > <ns1: payload >b</ns1: payload > </ns1:process>
to
変数には、例7-53に示すコンテンツが含まれています。
例7-53 変数のコンテンツ
<ns1:processResponse xmlns:ns1="http://xmlns.oracle.com/Event_ jws/Event/EventTest"> <ns1: payload >c</ns1: payload > </ns1:process>
bpelx:copyList
操作は、例7-54のようになります。
例7-54 bpelx:copyList
<assign> <bpelx:copyList> <bpelx:from variable="inputVariable" part="payload" query="/client:process/client:payload"/> <bpelx:to variable="outputVariable" part="payload" query="/client:processResponse/client:payload"/> </bpelx:copyList> </assign>
これにより、例7-55に示すto
変数が作成されます。
bpelx:validate
関数を使用すると、コードを検証して無効なXMLデータを識別できます。
この拡張要素の使用方法は次のとおりです。
assign
アクティビティのvalidate
属性内では、次のように使用します。
<assign bpelx:validate="yes|no">
...
</assign>
<bpelx:validate>
内で、スタンドアロン(assign
アクティビティなしで使用可能な拡張アクティビティ)として次のように使用します。
<bpelx:validate variables="NCNAMES" />
次に例を示します。
<bpelx:validate variables="myMsgVariable myPOElemVar" />
データ・シーケンスは、XMLで使用される最も基本的なデータ・モデルの1つです。しかし、データ・シーケンスの操作が重要な場合があります。BPELプロセス・サービス・コンポーネントで使用される最も一般的なデータ・シーケンス・パターンの1つが配列です。 XMLスキーマに基づき、データ・シーケンス定義はその属性maxOccurs
から識別できます。この属性が、1より大きい値に設定されているか、unboundedとしてマークされています。詳細は、XMLスキーマ仕様(http://www.w3.org/TR
)を参照してください。
この項では、BPELでのデータ・シーケンスの基本的な操作方法の例をいくつか示します。ただし、ループやエンドポイントの動的参照の実行など、その他の要件が存在します。 その他のコード例およびBPELでのデータ・シーケンス操作に関する実際の使用例の詳細は、http://www.oracle.com/technology/sample_code/products/bpel
を参照してください。次の各項では、データ・シーケンス操作の特定の要件について説明します。
必要な要素索引が設計時にわかっているとき、XPath機能を使用してデータ・シーケンス要素を選択する方法を次の2つの例で示します。これらのケースでは、最初の要素です。
例7-56の中で、addresses[1]
はアドレスのデータ・シーケンスの最初の要素を選択します。
例7-56 データ・シーケンス要素の選択
<assign> <!-- get the first address and assign to variable address --> <copy> <from variable="input" part="payload" query="/tns:invalidLoanApplication/autoloan:application /autoloan:customer/autoloan:addresses[1]"/> <to variable="address"/> </copy> </assign>
この問合せでは、addresses[1]
はaddresses[position()=1]
と同じです。ここで、position
はコアXPath関数の1つです(『XML Path Language(XPath)Specification』の第2.4項および第4.1項を参照)。 例7-57の問合せでは、position
関数を明示的にコールして、アドレスのデータ・シーケンスの最初の要素を選択します。次に、そのアドレスのstreet
要素(アクティビティで変数street1
に割り当てられます)を選択します。
例7-57 position関数の使用
<assign> <!-- get the first address's street and assign to street1 --> <copy> <from variable="input" part="payload" query="/tns:invalidLoanApplication/autoloan:application /autoloan:customer/autoloan:addresses[position()=1] /autoloan:street"/> <to variable="street1"/> </copy> </assign>
WSDLファイルで入力変数の定義とそのペイロード・パートを確認する際、addressesフィールドの定義に到達するまでに、いくつかのレベルを下っていきます。そこで、maxOccurs="unbounded"
属性が見つかります。2つのXPath索引付けメソッドは機能的には同じであり、どちらを使用してもかまいません。
データ・シーケンスの実行時のサイズ、つまりシーケンス内のノードまたはデータ項目の数を知る必要がある場合は、XPath組込み関数count()
とBPEL組込み関数getVariableData()
を組み合せて使用することで取得できます。
例7-58のコードは、item
シーケンス内の要素数を計算し、それを整数変数lineItemSize
に割り当てています。
多くの場合、データ・シーケンスへの索引付けに動的な値が必要になることがあります。つまり、シーケンスのn
番目のノード(n
の値は実行時に定義)の取得が必要な場合です。この項では、式の末尾にXPathを適用して動的な索引付けを行う方法について説明します。
例7-59に示す動的索引付け方法では、XPathをbpws:getVariableData()
の最後の引数として使用するのではなく、bwps:getVariableData()
の結果の末尾にXPathを適用します。 末尾のXPathは、位置述語内の整数型の索引変数(つまり、[...]
)を参照します。
例7-59 動的索引付け
<variable name="idx" type="xsd:integer"/> ... <assign> <copy> <from expression="bpws:getVariableData('input','payload' )/p:line-item[bpws:getVariableData('idx')]/p:line-total" /> <to variable="lineTotalVar" /> </copy> </assign>
実行時に、idx
整数変数の値として2
が格納されるとします。前述のfrom
内の式は、次の式と同じです。
<from expression="bpws:getVariableData('input','payload' )/p:line-item[2]/p:line-total" />
XPathがbwps:getVariableData()
関数の末尾に使用される場合とこの関数内で使用される場合では、XPathの使用方法に多少の違いがあります。同じ例(payload
が要素p:invoice
のメッセージ・パートである例)を使用すると、XPathをgetVariableData()
関数内で使用する場合は、ルート要素名(/p:invoice
)をXPathの先頭に指定する必要があります。
次に例を示します。
bpws:getVariableData('input', 'payload','/p:invoice/p:line-item[2]/p:line-total')
XPathをbwps:getVariableData()
関数の末尾に使用する場合、ルート要素名をXPath内に指定する必要はありません。
次に例を示します。
bpws:getVariableData('input', 'payload')/p:line-item[2]/p:line-total
これは、getVariableData()
関数で返されるノードがルート要素であるためです。ルート要素名をXPathで再指定すると重複になり、XPathの標準セマンティクスでは不正となります。
assign
アクティビティでbpelx:append
拡張要素を使用すると、BPELプロセス・サービス・コンポーネントは既存の親要素に新しい要素を追加できます。 例7-60に例を示します。
例7-60 bpelx:append拡張要素
<assign name="assign-3"> <copy> <from expression="bpws:getVariableData('idx')+1" /> <to variable="idx"/> </copy> <bpelx:append> <bpelx:from variable="partInfoResultVar" part="payload" /> <bpelx:to variable="output" part="payload" /> </bpelx:append> ... </assign>
この例のbpelx:append
ロジックにより、partInfoResultVar
変数のペイロード要素が、output
変数のペイロード要素に子として追加されます。 つまり、output
変数のペイロード要素が親要素として使用されます。
2つのシーケンスを単一のデータ・シーケンスにマージできます。 このパターンは、データ・シーケンスが配列内にある場合(つまり、互換性のあるタイプのデータ項目のシーケンスの場合)によく使用されます。例7-61に示すassign
の下の2つのappend
操作は、データ・シーケンスのマージ方法を示しています。
例7-61 append操作によるデータ・シーケンスのマージ
<assign> <!-- initialize "mergedLineItems" variable to an empty element --> <copy> <from> <p:lineItems /> </from> <to variable="mergedLineItems" /> </copy> <bpelx:append> <bpelx:from variable="input" part="payload" query="/p:invoice/p:lineItems/p:lineitem" /> <bpelx:to variable="mergedLineItems" /> </bpelx:append> <bpelx:append> <bpelx:from variable="literalLineItems" query="/p:lineItems/p:lineitem" /> <bpelx:to variable="mergedLineItems" /> </bpelx:append> </assign>
genEmptyElem
関数では、空要素の配列と等価の機能がXML構造に生成されます。この関数は、次の引数をとります。
genEmptyElem('ElemQName',int?, 'TypeQName'?, boolean?)
次の点に注意してください。
最初の引数では、空要素のQName
を指定します。
2番目の引数はオプションで整数型であり、空要素の数を指定します。指定されていない場合、デフォルトのサイズは1
です。
3番目の引数はオプションで、生成される空の名前のxsi:type
となるQName
を指定します。このxsi:type
パターンは、SOAPENC:Array
に相当します。指定されていないか、空の文字列である場合、xsi:type
属性は生成されません。
4番目の引数は、オプションでブール型であり、生成される空の要素において、XSD-nillableがtrueの場合に、XSI - nil
をtrueにするかどうかを指定します。デフォルト値はfalse
です。指定されていないか、false
である場合、xsi:nil
は生成されません。
例7-62に、po
の下で10
個の空の<lineItem>
要素を使用して注文書(PO)を初期化するappend
文を示します。
例7-62 append文
<bpelx:assign> <bpelx:append> <bpelx:from expression="ora:genEmptyElem('p:lineItem',10)" /> <bpelx:to variable="poVar" query="/p:po" /> </bpelx:append> </bpelx:assign>
この例のgenEmptyElem
関数は、次のように埋込みXQuery式で置き換えることができます。
ora:genEmptyElem('p:lineItem',10) == for $i in (1 to 10) return <p:lineItem />
この関数により生成される空要素は、通常は無効なXMLデータです。空要素の作成後に、さらにデータの初期化を実行します。前述と同じ例を使用して、次の操作を実行できます。
空のlineItem
要素に属性要素と子要素を追加します。
copy
操作を実行して空要素を置き換えます。たとえば、flowNアクティビティの下で、この等価配列内の個別エントリにWebサービスの結果からコピーします。
Oracle BPEL Process Managerは、Simple Object Access Protocol(SOAP)でエンコードされた配列(soapenc:arrayType
)を限定的にサポートしています。
SOAP配列を処理するために、次のいずれかの方法を検討してください。
サービスをラッパーで囲むと、BPELプロセス・サービス・コンポーネントがドキュメント・リテラル・ラッパー・サービスと通信するようになり、ラッパー・サービスによりsoapenc:arrayType
を使用する基礎となるサービスがコールされます。
soapenc:arrayType
を持つサービスをBPELからコールします。ただし、XMLメッセージはBPELコード内に手動で構成します(手動による構成部分が増えます)。 このアクションにより、サービスの変更やラップを回避できます。ただし、そのサービスをBPELからコールするたびに、余分な手順が必要になります。
ネイティブ・フォーマット・ビルダー配列識別子環境での処理には、ノードの親ノードに関する情報が必要です。 reportSAXEvents
APIが使用されるため、通常、この情報はアウトバウンド・メッセージ・シナリオには使用できません。 ネイティブ・スキーマのnxsd:useArrayIdentifiers
をtrue
に設定することで、アウトバウンド・メッセージ・シナリオにDOM解析を使用できるようになります。 大規模なペイロードによりパフォーマンスの低下につながる可能性があるため、この設定には注意が必要です。
<?xml version="1.0" ?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:nxsd="http://xmlns.oracle.com/pcbpel/nxsd"
targetNamespace="http://xmlns.oracle.com/pcbpel/demoSchema/csv"
xmlns:tns="http://xmlns.oracle.com/pcbpel/demoSchema/csv"
elementFormDefault="qualified"
attributeFormDefault="unqualified" nxsd:encoding="US-ASCII"
nxsd:stream="chars" nxsd:version="NXSD" nxsd:useArrayIdentifiers="true">
<xsd:element name="Root-Element">
....
</xsd:element>
</xsd:schema>
サービスは文字列を返すように定義されることがありますが、文字列の内容は実際にはXMLデータです。問題は、BPELではXMLデータの操作(XPath問合せや式などを使用)はサポートされていますが、変数またはフィールドが文字列型の場合にこの機能が使用できないことです。 Javaでは、DOM関数を使用して文字列を構造化されたXMLオブジェクト・タイプに変換します。同じことが、BPEL XPath関数parseEscapedXML
を使用して実行できます。
parseEscapedXML
関数はXMLデータを受け取り、DOMによって解析し、型指定されたBPEL変数に割当て可能な構造化XMLデータを返します。 例7-63に例を示します。
例7-63 文字列からXML要素への変換
<!-- execute the XPath extension function parseEscapedXML('<item>') and assign to a variable --> <assign> <copy> <from expression="ora:parseEscapedXML( '<item xmlns="http://samples.otn.com" sku="006"> <description>sun ultra sparc VI server </description> <price>1000 </price> <quantity>2 </quantity> <lineTotal>2000 </lineTotal> </item>')"/> <to variable="escapedLineItem"/> </copy> </assign>
前述のすべての例はドキュメント形式のWSDLファイルに対応しており、メッセージは例7-64に示すようにXMLスキーマのelement
で定義されます。
例7-64 XMLスキーマ要素の定義
<message name="LoanFlowRequestMessage"> <part name="payload" element="s1:loanApplication"/> </message>
これは、例7-65に示すように、メッセージがXMLスキーマのtype
で定義される、RPC形式のWSDLファイルとは異なります。
例7-65 RPC形式タイプ定義
<message name="LoanFlowRequestMessage"> <part name="payload" type="s1:LoanApplicationType"/> </message>
2つのWSDLメッセージ形式ではXPath問合せの構成方法に違いがあるため、これはこの章の記述に影響します。 RPC形式のメッセージの場合、最上位要素(およびXPath問合せ文字列の最初のノード)はパート名(例7-65ではpayload
)です。ドキュメント形式では、最上位ノードは要素名(たとえばloanApplication
)です。
例7-66および例7-67は、LoanServices
という名前のアプリケーションがRPC形式の場合に、XPath問合せ文字列がどのようになるかを示しています。
例7-66 RPC形式のWSDLファイル
<message name="LoanServiceResultMessage"> <part name="payload" type="s1:LoanOfferType"/> </message> <complexType name="LoanOfferType"> <sequence> <element name="providerName" type="string"/> <element name="selected" type="boolean"/> <element name="approved" type="boolean"/> <element name="APR" type="double"/> </sequence> </complexType>
BPELの通信アクティビティ(invoke、receive、replyおよびonMessage)は、指定のメッセージ変数を介してメッセージを送受信します。これらのデフォルト・アクティビティでは、各方向で1つの変数の操作が許可されます。たとえば、invokeアクティビティにはinputVariable
およびoutputVariable
属性があります。この2つの属性にそれぞれ変数を1つ指定できます。関連する特定の操作で使用するペイロード・メッセージが各方向で1つのみの場合は、これで十分です。
ただし、WSDLは1つの操作での複数のメッセージをサポートしています。SOAPの場合、SOAPヘッダーとしてメイン・ペイロード・メッセージとともに複数のメッセージを送信できます。ただし、BPELのデフォルトの通信アクティビティは、追加のヘッダー・メッセージに対応できません。
Oracle BPEL Process Managerでは、デフォルトのBPEL通信アクティビティをbpelx:headerVariable
拡張要素で拡張することで、この問題を解決しています。 例7-68に、拡張要素の構文を示します。
例7-68 bpelx:headerVariable拡張要素
<invoke bpelx:inputHeaderVariable="inHeader1 inHeader2 ..." bpelx:outputHeaderVariable="outHeader1 outHeader2 ..." .../> <receive bpelx:headerVariable="inHeader1 inHeader2 ..." .../> <onMessage bpelx:headerVariable="inHeader1 inHeader2 ..." .../> <reply bpelx:headerVariable="inHeader1 inHeader2 ..." .../>
この項では、SOAPヘッダーを受信するBPELファイルとWSDLファイルの作成方法を、例を挙げて説明します。
BPELでSOAPヘッダーを受信する手順は、次のとおりです。
ヘッダー・メッセージとそれをSOAPリクエストにバインドするSOAPバインディングを宣言するWSDLファイルを作成します。 例7-69に例を示します。
例7-69 WSDLファイルのコンテンツ
<!-- custom header --> <message name="CustomHeaderMessage"> <part name="header1" element="tns:header1"/> <part name="header2" element="tns:header2"/> </message> <binding name="HeaderServiceBinding" type="tns:HeaderService"> <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/> <operation name="initiate"> <soap:operation style="document" soapAction="initiate"/> <input> <soap:header message="tns:CustomHeaderMessage" part="header1" use="literal"/> <soap:header message="tns:CustomHeaderMessage" part="header2" use="literal"/> <soap:body use="literal"/> </input> </operation> </binding>
例7-70に示すように、ヘッダー・メッセージ変数を宣言し、bpelx:headerVariable
を使用してヘッダーを受信するBPELソース・ファイルを作成します。
例7-70 bpelx:headerVariableの使用
<variables> <variable name="input" messageType="tns:HeaderServiceRequestMessage"/> <variable name="event" messageType="tns:HeaderServiceEventMessage"/> <variable name="output" messageType="tns:HeaderServiceResultMessage"/> <variable name="customHeader" messageType="tns:CustomHeaderMessage"/> </variables> <sequence> <!-- receive input from requestor --> <receive name="receiveInput" partnerLink="client" portType="tns:HeaderService" operation="initiate" variable="input" bpelx:headerVariable="customHeader" createInstance="yes"/>
この項では、SOAPヘッダーの送信方法を例を挙げて説明します。
BPELでSOAPヘッダーを送信する手順は、次のとおりです。
composite.xml
でSCA参照を定義して、HeaderService
を参照します。
例7-71に示すように、カスタム・ヘッダー変数を定義して操作し、bpelx:inputHeaderVariable
を使用して送信します。
例7-71 bpelx:inputHeaderVariableの使用
<variables> <variable name="input" messageType="tns:HeaderTestRequestMessage"/> <variable name="output" messageType="tns:HeaderTestResultMessage"/> <variable name="request" messageType="services:HeaderServiceRequestMessage"/> <variable name="response" messageType="services:HeaderServiceResultMessage"/> <variable name="customHeader"messageType="services:CustomHeaderMessage"/> </variables> ... <!-- initiate the remote process --> <invoke name="invokeAsyncService" partnerLink="HeaderService" portType="services:HeaderService" bpelx:inputHeaderVariable="customHeader" operation="initiate" inputVariable="request"/>
BPELプロセス・サービス・コンポーネントは、最適化されたメッセージ転送最適化メカニズム(MTOM)フォーマットでSOAP添付ファイルを受信できます。 ただし、BPELプロセスは添付ファイルを内部的に処理できません。 かわりに、添付ファイルはXMLファイルの一部としてDOMに追加されます。 MTOM添付ファイルを使用するのではなく、Multipurpose Internet Mail Extensions(MIME)およびDirect Internet Message Encapsulation(DIME)のSOAP添付ファイルを使用することをお薦めします。