指令檔引擎版本 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-01-02” 而不是 “2010-1-2”。

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

這個範例顯示用於新增十進位填補零對齊的後綴,例如產生 “12.30” 和 “4.00” 而不是 “12.3” 和 “4”。這個範例會執行 3 個任務:四捨五入到小數點後 2 位數,必要時插入句號,以及填補零。

// 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 區塊中使用。它在 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