![]() ![]() ![]() ![]() ![]() ![]() | ![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
第11章
アクションは、すべてのComposerコンポーネントにおける作業の原子単位です。アクションは、カスタムアプリケーションを使用可能にする制御フローと論理構成要素を統括します。一部のアクションは、他のアクションよりも頻繁に使用され、特定の設計パターンは、Composerを使って作成したWebサービスアプリケーションで何度も使用されます。 この章では、Composerの使用時によく見られるアクションと設計パターンの一部について説明します。
exteNd Composerの設計側インストールには、サンプルプロジェクトが数個あり、そのうちの1つはActionExamples.spfと呼ばれます。 この章の例は、XMLマップコンポーネントへの入力としてInvoiceBatchテンプレートを使用した場合に基づいています。
Composerの[ファイル]メニューからActionExamples.spfを開くと、例を参照しながら作業を進めることができます。ファイルは、次の場所に保存されています。
..\exteNdComposer\Samples\ActionExamples\ActionExamples.spf
この章でのチュートリアルプロジェクトの場合と同様に、他のアクションモデルの例を参照することもできます。
exteNd Composerの強力なツールの1つは、要素のマッピングです。異なる構造のDOMツリー間で要素をマップし、XMLドキュメント間でデータを渡すことができます。
注記: Composerでの基本的なマッピングの動作の概要については、マップのタイプの表を参照してください。
Composerで作成した要素のマッピングの多くは、2つのDOMのリーフ要素(端末ノード)間で行われます。 たとえば、入力パートの製品SKUを出力パートの製品パーツ番号にマップする必要があるとします。 この場合、サービスを実行すると、2つのパート間で転送が行われ、入力XMLドキュメントからのSKUが出力XMLドキュメントのパーツ番号に書き込まれます。
2つのリーフ要素をマッピングする1つの方法は、XMLマップコンポーネントエディタの[入力]ペインと[出力]ペインでリーフ要素を選択し、マップアクションを追加することです。
注記: デフォルトでは、Composerのマップアクションによって「要素」データは転送されますが、属性データは転送されません。
アクションモデルペインで、マップアクションを配置する行を選択します。すると、選択した行の下に新しいマップアクションが挿入されます。
[マップ]ダイアログボックスが表示されたら、[OK]をクリックします。すると、入力要素から出力要素へのマッピングが自動的に作成されます。
次に説明するように、Composerの「ドラッグ&ドロップ」機能を使用して、入力リーフ要素を出力リーフ要素にマップすることもできます。
要素をマップする2番目の方法は、「ペアレント要素」をターゲットパートにマップすることです。ペアレント要素がマップされると、そのチャイルド要素と属性もすべてマッピングに含まれます。 たとえば、Line_Item
というペアレント要素を選択し、Item_SKU、Item_Description、Item_Quanity
、およびItem_Cost
を含むチャイルド要素がこの要素に含まれているとします。 この場合に、Line_Item
要素を、PO_Line
という名前の出力パートの要素にマップすると、 結果として作成されたマップアクションにより、元のブランチの構造は維持しながら、Line_Item
要素とそのチャイルド要素すべてが、出力のPO_Line
要素に転送されます。
注記: Composerのマップアクションで、デフォルトのマッピング動作は、上書きすることができます。 参照
ドラッグアンドドロップ機能を使用してリーフ要素をマップするで説明するように、Composerのドラッグアンドドロップ機能を使用して、入力ペアレント要素を出力ペアレント要素にマップすることもできます。
要素をマップする3番目の方法は、子孫要素なしでペアレント要素をマップすることです。基本的には、ハイレベルのデータをマップし、子孫要素のデータは無視します。 たとえば、Invoiceという要素をマップし、この要素に子孫要素が含まれている場合、出力パートはInvoice要素に関するデータのみを受信します。
注記: デフォルトのマップアクションの動作では、子孫要素が転送されるため、ECMAScriptメソッドを作成して要素名に適用し、その要素のみをマップする必要があります。
チャイルド要素のないペアレント要素のマップアクションは、次の図のとおりです。
場合によっては、形式が異なる2つの要素をマップしなければならないことがあります。たとえば、入力DOMの要素リーフは、4つの数字と大文字(1234CAT)から形成されており、出力要素リーフは、小文字と6つの数字(cat001234)から形成されているような場合があります。
Composerには、DOM間でデータを適切にマップできるよう、要素の形式を変換するための方法が3つあります。これらの3つの方法は、すべてマップアクションから使用できます。
コンテンツエディタを使用すると、入力要素の形式とコンテンツを変更して、出力要素に必要な形式とコンテンツに一致させることができます。コンテンツエディタでは、入力データを小さな部分にスライスしたり、それらの部分を互いに関連する異なる場所に移動したり、新しい部分を追加したり、一部の部分を省略したり、個々の部分に関数を適用したりできます。
[アクション]メニューから、[新規アクション]、[マップ]の順に選択します。すると、[マップ]ダイアログボックスが表示されます。
[コンテンツエディタ]ボタンの横にあるチェックボックスをオンにします。これにより、[コンテンツエディタ]ボタンが有効になります。
[サンプル]フィールドで、切り取りを開始する場所に上部スライダを移動し、切り取りを終了する場所に下部スライダを移動します。これらのスライダにより、入力データから下位文字列を切り取る方法が決定されます。
サンプルの各部分に対して、手順6から8を繰り返します(任意の順序で)。このようにして、元の入力の一部(下位文字列)から新しい文字列を作成できます。
[変更]をクリックします。すると、[コンテンツ領域の変更]ダイアログボックスが表示されます。
注記: [切り取りを開始する文字]フィールドには、文字列で切り取りを開始する場所にある文字が表示されます。最初の[オカレンス]フィールドには、切り取りが行われる場合が表示されます。前の図では、Tの文字が初めて現れたときに、文字列の切り取りが開始されます。[切り取りを終了する文字]フィールドには、文字列で切り取りを終了する場所にある文字が表示されます。2番目の[オカレンス]フィールドには、切り取りが行われる場合が表示されます。[オフセット]フィールドには、オブジェクトが開始する元の文字列の最初から数えた文字数が表示されます。[長さ]フィールドには、オブジェクトの長さが表示されます。
[スクリプト式]フィールドでは、ECMAScript Expression Builderをサポートしています。コンテンツエディタによって作成されたコンテンツ領域では、適用される式ビルダの完全な機能を使用できます。
注記: %rは、関数を適用するコンテンツ領域を表すローカル変数です。 たとえば、uCase()関数をコンテンツ領域に適用する場合、 uCase(%r)のようにスクリプト式を記述します。
オブジェクトを選択し、[定数]チェックボックスをオンにしてから定数文字列を入力すると、そのオブジェクトに定数を割り当てることができます。
コンテンツエディタを使用した文字列形式のマッピングが完了したら、[OK]をクリックして変更内容を保存し、コンテンツエディタを閉じます。
コードテーブルを使用してマップすると、入力パートで使用したあるコードセットを、出力パートで使用した別のコードセットに自動的に変換できます。コードテーブルを使用して要素を変換するには、コードテーブルとコードテーブルマップがすでに作成されている必要があります。
[アクション]メニューから、[新規アクション]、[マップ]の順に選択します。すると、[マップ]ダイアログボックスが表示されます。
コンテンツエディタでは要素の形式構造を十分に変換できないという状況が生じる可能性があります。たとえば、日付形式(例: 5/23)から月の数字を抽出して、月の名前(May 23)に変換しなければならないことがあります。このような場合、ECMAScriptおよびXPathカスタム関数を作成して、要素式に適用すると、カスタム変換を実行できます。
Composerには、サンプルカスタムスクリプト関数のライブラリが用意されており、次のカテゴリで編成されています。
関数のカテゴリは、\exteNd\Samples\CustomScripts
サブディレクトリからインポートできます。
[アクション]メニューから、[新規アクション]、[マップ]の順に選択します。すると、[マップ]ダイアログボックスが表示されます。
注記: 関数を使用してマップアクション内で要素データを変換する場合は、関数の結果によって完全修飾DOM要素名が返されることを確認してください。
マップアクション外で要素のデータを変換する場合、関数アクションを使用します。 関数アクションを参照してください。
「Userfunc:」は、 XPath式でECMAScript関数を使用できるようにするブリッジNovell拡張メソッドです。また、XPathには、ノードセット、文字列、ブール、および数値として分類されるネイティブ関数の限定されたセットもあります。 これらの関数では、userfunc:キーワードを使用する必要は ありません。詳細については、exteNd/Docs/XPathディレクトリに保存されている「XMLパス言語(XPath)」ガイドを参照してください。
高度なアクションに関する章では、3つの繰り返しアクションと、アクションモデル内で反復処理を実行するために繰り返しアクションが使用される方法について学習します。 この節では、繰り返しアクションについて詳しく説明し、繰り返しアクションを使用してデータ入力パートと出力パートの読み込み、マッピング、および書き込みを行う方法について示します。
繰り返しアクションには、次の3種類のループがあります。ルールは次のとおりです。
XMLでは、ドキュメントで要素のインスタンスを複数使用できます。インスタンスの数は、ドキュメントにより異なります。たとえば、請求書を含むXMLドキュメントを毎日受け取らなければならない場合があります。XMLドキュメントに含まれる請求書の数は、毎日異なります。XMLドキュメントに含まれる請求書のインスタンス数を把握していない場合、入力XMLドキュメントの各請求書から出力XMLドキュメントに請求書数を転送しようとすると、問題が生じます。ただし、要素の繰り返しアクションを使用すれば、この問題が解決します。
要素の繰り返しアクションでは、複数回発生する要素をマークできます。その後、マークされた要素の各インスタンスに対して(そのようなインスタンスがなくなるまで)1つまたは複数のアクションを実行する処理ループを設定します。前の例では、請求書数を転送するマップアクションが処理ループに1つ含まれている可能性があります。
要素の繰り返し処理ループを使用すると、複数のアクションを処理できます。最も単純な場合、繰り返しループには、入力DOMから出力DOMに現在のインスタンスの値を転送するマップアクションが1つだけ含まれます。処理ループで複数のアクションを設定することもできます。 たとえば、現在の値を転送するマップアクションと、ファイルに記録し、転送ごとに監査情報を作成するログアクションの2つを設定する、といった具合です。
要素の繰り返しアクションを追加する最初の手順は、繰り返し処理を実行する場所にアクションモデルペイン内でカーソルを置くことです。
アクションモデルペインで、要素の繰り返しアクションを配置する行を選択します。すると、選択した行の下に新しいアクションが挿入されます。
コンテキストメニューを使用して、[要素の繰り返し]を選択します。すると、[要素の繰り返し]ダイアログボックスが表示されます。
[常に新規の出力要素を作成する]チェックボックスをオンにすると、既存の要素を更新していくのではなく、その都度新規に要素を追加していく形の繰り返しアクションになります。
要素の繰り返しアクションを作成したら、ループ内にマップ(またはその他の)アクションを追加できます。たとえば、入力XMLドキュメントから出力XMLドキュメントに請求書数要素を単に転送するには、次の図に示すようにマップアクションを定義します。
ここでは、XPathコンテキストとして繰り返し別名が使用されています。別名は繰り返しアクションで定義され、実際のDOM名とパスに解決されます。
[ソース]フィールドでは、入力パート(seINVOICES/INVOICEHEAD/INVOICENO)の場所からのデータが出力パート(teMYINVOICES/INVOICENO)の場所に転送されるよう指定します。
要素の繰り返しアクションとマップアクションは、アクションモデルペインに表示される必要があります(次の図を参照)。
受信したXMLドキュメントの形式は、常にビジネスプロセスの条件を満たす形式であるとは限りません。たとえば、XMLドキュメントに異なる販売者からの請求書が含まれる場合があります。データは個々の請求書として受信されますが、B2Bトランザクションのコンテキストでは、データを要約してマネージャにサマリデータを送信すると同時に、会計支払部署に請求書データを送信しなければならないことがあります。
グループの繰り返しアクションでは、データを再作成して、データを集約計算するためのフレームワークを確立できます。 グループ化すると、入力パートで繰り返し要素を選択し、その繰り返し要素のすべてのインスタンス(兄弟)全体で固有な値に基づき、より少数の要素を作成できます。 これにより、請求書全体(一部の請求書では販売者値が同じ)で複数の販売者要素を使用する代わりに、出力パートの固有な販売者値それぞれに対して1つの要素を使用することになります。
グループの繰り返しアクションでは、グループの固有な値それぞれに対して実行する処理ループを設定します。販売者あたりに1つの要素を設定したら、処理ループにマップアクションを追加して、各販売者における請求書の数を計算できます。また、各販売者の下に個々の請求書数をリストすることもできます。グループの繰り返し処理ループをマップコマンドと結合させると、元のXMLドキュメントとは構造とデータが異なる新しいXMLドキュメントを作成できます。
グループの繰り返しアクションを作成するには、次の3つのタスクを完了する必要があります。
[グループ要素/属性]フィールドで、選択した要素の完全な名前を指定します。希望する場合は、このリストに別の要素を追加して、異なる要素の2つまたはそれ以上の値を連結させてグループを作成することもできます。
入力パート要素に基づいてグループを作成したら、「グループの繰り返し」アクションを作成できます。
アクションモデルで、グループの繰り返しアクションを配置する行を選択します。すると、選択した行の下に新しいアクションが挿入されます。
[アクション]メニューから、[新規アクション]>[繰り返し]>[グループの繰り返し]の順に選択します。すると、[グループの繰り返し]ダイアログボックスが表示されます。
オプションの[スクリプト式の指定]フィールドでは、グループ処理から一部の繰り返し要素を選択的に除外できます。式を入力するか、または[式ビルダ]ボタンをクリックして、グループに含める要素を決定するECMAScript式を記述します。
オプションの[ターゲット]フィールドでは、「グループの繰り返し」アクション内でマップされたデータを配置する、出力パート内での位置を指定できます。 [ターゲット]フィールドで別名を入力し、パートを選択してXPathを指定します。この別名は、ループ内のマップアクションに対するターゲットコンテキストとして使用されます。
グループの繰り返しアクションを作成したら、ループ内に1つまたは複数のマップアクションを追加できます。 入力パート要素および出力パート要素としてグループを使用するマップアクションは、次の図のとおりです。
ここでは、ドットが使用されています。これは、コンテキスト「sgTHESELLERNAME」で解決される現在の場所(以前に、アクションモデルのグループの宣言アクションで定義しました)を示しています。
グループの繰り返しアクションとマップアクションは、アクションモデルペインに表示される必要があります(次の図を参照)。
Repeat Whileアクションでは、定義する任意の条件に基づいて処理ループが作成されます。これによって、要素の繰り返しアクションやグループの繰り返しアクションの実行時とは異なる柔軟性が、繰り返しループの作成時に提供されます。この2つのアクションでは、両方ともループはドキュメントまたはDOMのデータに基づきます。ただし、Repeat Whileアクションを使用すると、処理ループを有効なXPathやECMAScript式に基づかせることができます。
たとえば、ループの実行を、システムクロックを確認してループから抜け出すときを決定するECMAScript式に基づかせることができます。また、別の例では、ディレクトリ内でのファイルの有無にループを基づかせることができます。この場合、ループ内のアクションによってファイルが処理され、ファイルがなくなった場合にのみループが終了します。
Repeat Whileアクションを作成するには、次のタスクを実行する必要があります。
アクションモデルで、Repeat Whileループを配置する行を選択します。すると、選択した行の下にループが挿入されます。
[アクション]メニューから、[新規アクション]>[繰り返し]>[Repeat While]の順に選択します。すると、[Repeat While]ダイアログボックスが表示されます。
[While]スクリプト式フィールドは、ECMAScript式を入力する場所です。falseと評価された場合、ループの実行は停止します。[式ビルダ]ボタンをクリックして式を入力したり、事前に記述された式のリストから式を選択したりすることもできます。
[インデックス変数]フィールドでは、ループカウンタの名前を作成できます。このカウンタは、ループが実行されるたびに増分します。 [While]式の値を取得し、ループ処理をさらに制御できます。
オプションとして、[ターゲット]に情報を入力できます。別名を入力し、[XPath]とDOM要素を選択するか、または[式]を選択して有効な式を入力します。また、[式ビルダ]ボタンをクリックして、式を作成することもできます。
Repeat Whileループを作成したら、ループ内に1つまたは複数のマップアクションを追加できます。2つのマップアクションを使用したRepeat Whileループは、次の図のとおりです。
集約計算には、アクション例プロジェクトの [008]集約計算というコンポーネント内にある次の例が含まれます。
請求書を処理するコンポーネントがあり、請求書全体で全品目の合計(課税前)を計算したいとします。
これには、XPath構文を使用した単純なECMAScript式を使用します。まず、マップアクションを作成し、[コピー元]の[式]ラジオボタンをオンにします。次のECMAScript式を入力します。
$Input.XPath(・/LINETOTAL・.sum()
[ターゲット]で[出力]を選択し、結果を受け取るXPathを指定します。
MYINVOICEBATCH/LINEITEMTOTALa.
[ソース]の式では、親子関係に関係なく、LINETOTALというラベルの入力ノードをすべて選択するためにXPathの//パターンシンボルが使用され、その後、Novell集約メソッドの sum()
が適用されます。
注記: XMLテンプレートは、[出力]に対して指定されていないため、ダイナミックに作成されます(つまり、マップアクションでは、「マップ先」コントロールで指定した要素が検索されない場合に、この要素が作成されます)。
アクションの例は、次のとおりです。
請求書を処理するコンポーネントがあり、請求書金額の最大合計を検索したいとします。
複数のINVOICE間で要素の最大を検索するには、[コピー元]の仕様で「max」メソッドを指定できます。これにより、max()
関数のコンテキストが確立されます。その後、最大を検索する要素が「TOTALS.INVOICETOTAL」に存在するDOMツリーでのポイントまで、仕様を続行できます。
アクションの例は、次のとおりです。
前の請求書の例の続きとして、最大合計に一致する請求書を1つ選択したいとします。
すべてのINVOICEを表示して、その中から1つだけ選択するには、[ソース]の仕様で「where」メソッドを指定できます(whereメソッドでは、各INVOICEを処理することを意味します)。仕様は、各INVOICEのTOTALS\INVOICETOTALと、すべてのTOTALS.INVOICETOTALの最大値を比較して、続行されます。最大値が検索され、各INVOICEの値に対して比較されます。一致が見つかると、仕様が続行され、INVOICENOが取得されます。
アクションの例は、次のとおりです。
Copyright © 2004 Novell, Inc. All rights reserved. Copyright © 1997, 1998, 1999, 2000, 2001, 2002, 2003 SilverStream Software, LLC. All rights reserved. more ...