スクリプト・エンジン・バージョン2以上に関する注意

エンジン・バージョン2以上を使用するスクリプトには、XPath 2の機能を利用するためにいくつかの追加の構文が必要です。一般に、宣言された変数は文字列とみなされます。これは、算術文を作成する場合に、変数のデータ型を整数、数値または日付として明示的に宣言する必要があることを意味します。

注意: 特に記載されていないかぎり、このトピックのXPathの例はすべて、バージョン1エンジン用、つまり、XPath 1を意味します。XPath 1を使用して機能する文がXPath 2で機能するとはかぎりません。これは、算術を実行する場合に特に当てはまります。次の例を参照してください。

日時計算

XPathの日時および期間のデータ型は、計算操作(+、-、*など)および関数をサポートしており、数値計算に'1 + xs:integer(value)'を使用するのと同じ方法で時間計算に使用できます。

時間の比較:

if ("(xs:dateTime(fn:current-dateTime()) - xs:dateTime($updateDateTimeX))
   ge xs:dayTimeDuration(concat('PT', BO/hoursBetweenStatisticsUpdate, 'H'))")
   goto 60;
end-if;

日付と日付の比較:

if ("xs:date(parm/endDate) < xs:date(parm/startDate)")
   terminate with error (11108, 11507 element='endDate');
end-if;

今日の日付との日付の比較:

if ("xs:date(parm/startDate) <= xs:date($CURRENT-DATE)")
   terminate with error (11108, 11507 element='endDate');
end-if;

月末の計算:

// covert to ISO
move "concat($year,'-',$mon2,'-01T00:00:00')" to $monthStart; 
 
// calculate
move "xs:dateTime($monthStart) + xs:yearMonthDuration('P1M') - xs:dayTimeDuration('P0DT1S')" 
  to $monthEnd;
 
// convert from ISO to OUAF
move "concat($year,'-',$mon2,'-',substring(string($monthEnd),9,2),'-23.59.59')" to $endDateTime;
注意: XPathの日付/時間/期間の書式はISO標準を使用しており、フレームワークでサポートされている書式との間で変換が必要です。

文字列形式での日時の比較

ISOのような日時の文字列形式では、YYYY MM DD HH MM SSシーケンスはゼロが埋め込まれて保持されます。セパレータに関係なく、この書式は比較操作に適しています。特に、フレームワークの書式であるYYYY-MM-DD.HH.MM.SSの日時の値は、=、!=に加えて、>、>=、<、<=の演算子とともに使用できます。

// retrieve framework date/time value
invokeBS 'CM-MAXMSRMT' using "CM-MAXMSRMT";
move "string(cm-MAXMSRMT/results[1]/measurementDateTime)" to $lastMsmtDT;
 
// construct another date/time
move "concat($year,'-01-01-00.00.00')" to $startDateTime;
 
// compare using string operators
if ("$lastMsmtDT >= $startDateTime")
    move "substring($lastMsmtDT,1,4)" to $latestMsrmtYear;

フレームワークとISOの間の日時の変換

フレームワーク書式からISOへの日時の変換は、日時計算にのみ必要です。比較は、フレームワーク書式で直接実行できます。フレームワーク書式とISOの日時書式との唯一の違いはセパレータです。

フレームワーク: YYYY-MM-DD.HH.MM.SS

ISO: YYYY-MM-DDTHH:MM:SS

フレームワーク書式からISOへの変換例:

move "concat(substring($ouafDT, 1, 10), 'T', translate(substring($ouafDT, 12),'.',':'))" to $isoDT;

ISOからフレームワーク書式への変換例:

move "concat(substring($isoDT, 1, 10), '.', translate(substring($isoDT, 12),':','.'))" to $ouafDT;

動的通貨スケールでの金額の端数処理

通貨が異なるとサポートされる小数点以下の桁数が異なるため、フレームワークには、指定の通貨に基づいて金額を端数処理するためのAPIが用意されています。

move "parm/amount" to $qnty;
move "currency/decimals" to $decimals;
move "fn:round(xs:decimal($qnty) * math:exp10(xs:double($decimals))) 
  div math:exp10(xs:double($decimals))" to "parm/roundedAmount";

シーケンスのループ

XPath 2では、ノード・リストのみでなく、一連の整数にforループを編成できます。

この例は、一連の月のループを示しています。これはXPathでのシーケンスを形成する構成です。見慣れているXPathノード・リストは、別のタイプのシーケンスです。

for ($month in "1 to 12")

この例は、指定された範囲の年の降順のループを示しています。

for ($year in "fn:reverse(parm/startYear to parm/endYear)")
     move "concat($year,'-01-01-00.00.00')" to $startDateTime;
     move "concat($year,'-12-31-23.59.59')" to $endDateTime;
     ...   

この例では、他のノード・リストにアクセスできるように、索引を使用したノード・リストのループを示しています。

for ($idx in "1 to count(parm/touData/touList)")
     move "parm/touData/touList[$idx]" to $tou;   // access any list with this index   

前述の構文は、たとえば、次の文のかわりに、索引を個別に維持する明瞭簡潔な代替手段として使用できます。

move “0” to $idx;
for ($item in "parm/touData/touList")
     move “1 + xs:integer($idx)” to $idx;

文字列の埋込みおよび小数の書式設定

これは特定の入力書式または出力書式設定で使用されます。ゼロ、空白および他のタイプの埋込みに適用されます。

この例は、「2010-1-2」のかわりに「2010-01-02」を作成するなど、日時コンポーネントのプリフィクス設定を示しています。

move "substring(concat('0',string($month)), string-length(string($month)), 2)" to $mon2; 

この例は、「12.3」と「4」のかわりに「12.30」と「4.00」を作成するなど、小数へのゼロ埋込み整列を追加するためのサフィックス設定を示しています。この例では、小数点以下2桁に端数処理して、必要な場合はピリオドを挿入し、ゼロを埋め込むという3つのタスクを実行します。

// round and zero-pad to 2 decimals
move "$item/amount" to $qty;
move "fn:round(xs:double($qty) * 100) div 100" to $qty;
move "string($qty)" to $qty;
move "concat(substring-before(concat($qty,'.'),'.'),'.',substring(concat(substring-after($qty,'.'),'00'),1,2))" to $qty;

三項操作

これは、if/elseブロックのかわりに単一の式で使用できるように、条件に基づいて2つの値から選択します。C/C++では「cond ? value1 : value2」、BASICでは「IFF(cond, value1, value2)」として知られています。XPathでは、構文は「if (cond) then value1 else value2」です。これは、最上位レベル・スクリプトのif文ブロックではないことに注意してください。

XPathでは、これは式であり、他の式と組み合せることが可能です。スクリプトでは、次のように使用できます。

move "if (string(D1-UnitOfMeasure/measuresPeakQuantity) = 'D1MP') then 'D1MX' else 'D1SM' " to $func;

パイプライン処理

スクリプトでは、ローカル関数がないため、再利用可能な一連の単純なコードの作成は容易ではなく、別のスクリプト・コールはコーディング上のオーバーヘッドであり、パラメータのパック/アンパックが必要です。類似するスクリプト・ステージ間での同じコード・ブロックのコピーと貼付けを回避するには、プロセス全体を個別の最上位レベル・ステップに分割するパイプライン化を検討してください。これは、パラメータの準備および出力の書式設定には一般的です。ステージ間の中間結果はparmサブ構造に格納できます。

このコードのかわりに:

if ("type = A")
   prepare params ...
   call services for A ...
   format output ...
end-if;
if ("type = B")
   prepare params ...
   call services for B ...
   format output ...
end-if;

この代替を検討:

prepare params ...

if ("type = A")
   call services for A ...
end-if;
if ("type = B")
   call services for B ...
end-if;

format output ...

XPath 2の機能

スクリプト・エンジン・バージョン2以上では、XQuery 1.0の関数および演算子、およびXQuery 1.0標準自体が少し制限されています。次に両方の仕様のURLを示します。最初のリンクにはXQueryから使用できる関数/演算子があります。

  • http://www.w3.org/TR/xpath-functions/

  • http://www.w3.org/TR/xquery/

次の関数はローカル・ファイル・システムのみアクセスできます。(httpのような他のプロトコルの場合、空のシーケンスが返されます。)

  • fn:doc

  • fn:collection