Motor skryptów wersja 2 i wyższe - uwagi
Tworzenie skryptów przy użyciu motoru w wersji 2 lub wyższej wymaga dodatkowej składni, aby móc wykorzystać funkcję języka XPath 2. Na ogół wszystkie zadeklarowane zmienne będą uznawane za ciąg tekstowy. Oznacza to, że w celu utworzenia instrukcji matematycznej, trzeba jawnie zadeklarować typ danych zmiennych jako liczby całkowite, liczby lub daty.
Arytmetyka daty i godziny
Typy danych Data/godzina i Dane interwału XPath obsługują operacje arytmetyczne ("+", "-", "*" itd.) i funkcje, których można używać do obliczeń czasu w ten sam sposób, co wyrażenie "1 + xs:integer(wartość)" jest używane do obliczeń liczbowych.
Porównywanie czasu trwania:
if ("(xs:dateTime(fn:current-dateTime()) - xs:dateTime($updateDateTimeX))
ge xs:dayTimeDuration(concat('PT', BO/hoursBetweenStatisticsUpdate, 'H'))")
goto 60;
end-if;
Porównywanie jednej daty z inną:
if ("xs:date(parm/endDate) < xs:date(parm/startDate)")
terminate with error (11108, 11507 element='endDate');
end-if;
Porównywanie daty z bieżącą datą:
if ("xs:date(parm/startDate) <= xs:date($CURRENT-DATE)")
terminate with error (11108, 11507 element='endDate');
end-if;
Obliczanie końca miesiąca:
// 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;
Porównywanie daty/godziny w formacie ciągu tekstowego
Każdy format ciągu tekstowego ISO dotyczący daty/godziny zachowuje kolejność RRRR MM DD HH MM SS, która jest uzupełniana zerami. Niezależnie od separatorów ten format będzie właściwy do operacji porównywania. W szczególności wartości daty/godziny w formacie framework "RRR-MM-DD.HH.MM.SS" można używać z operatorami "=", "!=", a także ">", ">=", "<", "<=".
// 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;
Przekształcanie daty/godzin między formatem framework i ISO
Przekształcanie daty/godziny z formatu framework na ISO jest niezbędne tylko do wykonywania operacji arytmetycznych na dacie/godzinie. Porównania można wykonywać bezpośrednio na formacie framework. Jedyną różnicą między formatem framework a formatami daty/godziny ISO są separatory:
Framework: "RRRR-MM-DD.HH.MM.SS"
ISO: "RRRR-MM-DDTHH:MM:SS"
Przykład przekształcania z formatu framework na ISO:
move "concat(substring($ouafDT, 1, 10), 'T', translate(substring($ouafDT, 12),'.',':'))" to $isoDT;
Przykład przekształcania z formatu ISO na framework:
move "concat(substring($isoDT, 1, 10), '.', translate(substring($isoDT, 12),':','.'))" to $ouafDT;
Zaokrąglanie kwot pieniężnych przy użyciu dynamicznej skali waluty
Ze względu na to, że różne waluty obsługują inną liczbę miejsc dziesiętnych, framework udostępnia interfejs API do zaokrąglania kwot pieniężnych na podstawie danej waluty.
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";
Zapętlanie sekwencji
W języku XPath 2 możliwe jest porządkowanie pętli for w sekwencji liczb całkowitych, a nie tylko listy węzłów.
Ten przykład przedstawia pętlę w zakresie miesięcy. To jest konstrukcja tworzenia sekwencji w języku XPath. Znana lista węzłów XPath jest kolejnym typem sekwencji.
for ($month in "1 to 12")
Ten przykład przedstawia pętlę w danym zakresie lat w kolejności malejącej:
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;
...
Ten przykład przedstawia pętlę w liście węzłów przy użyciu parametru "index", tak aby można było uzyskać dostęp do innych list węzłów:
for ($idx in "1 to count(parm/touData/touList)")
move "parm/touData/touList[$idx]" to $tou; // access any list with this index
Powyższej składni można używać jako prostej alternatywny osobnej obsługi indeksów, np. zamiast następującego kodu:
move “0” to $idx;
for ($item in "parm/touData/touList")
move “1 + xs:integer($idx)” to $idx;
Uzupełnianie ciągów tekstowych i formatowanie miejsc dziesiętnych
Tej funkcji można używać z konkretnymi formatami wejściowymi lub wyjściowymi. Dotyczy uzupełniania zerami, spacjami i innych typów uzupełniania.
W tym przykładzie przedstawiono wstawianie przedrostków do składników daty/godziny, np. utworzenie zapisu "2010-01-02" zamiast "2010-1-2".
move "substring(concat('0',string($month)), string-length(string($month)), 2)" to $mon2;
Ten przykład przedstawia dodanie przyrostka na potrzeby wyrównania liczby zer na miejscach dziesiętnych, np. utworzenie zapisu "12,30" i "4,00" zamiast "12,3" i "4". W tym przykładzie wykonywane są trzy zadania: zaokrąglenie do 2 miejsc dziesiętnych, wstawienie przecinka w razie potrzeby oraz uzupełnienie zerami.
// 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;
Operacje trzyelementowe
Operacje umożliwiają wybór między wartościami na podstawie warunku, dzięki czemu można używać pojedynczego wyrażenia zamiast bloku if/else. Tego typu operacje są znane w języku C/C++ jako "warunek ? wartość 1 : wartość 2" lub języku BASIC jako "IFF(warunek, wartość1, wartość2)". W języku XPath składnia jest następująca: "if (warunek) then wartość1 else wartość2". Należy pamiętać, że to nie jest blok instrukcji if najwyższego poziomu skryptu.
W języku XPath to jest wyrażenie, które można połączyć z innymi wyrażeniami. W skryptach można go używać jako:
move "if (string(D1-UnitOfMeasure/measuresPeakQuantity) = 'D1MP') then 'D1MX' else 'D1SM' " to $func;
Przetwarzanie potoków
W skryptach nie można łatwo tworzyć prostego fragmentu kodu wielokrotnego użytku, ponieważ nie ma w nich funkcji lokalnych, a wywołanie osobnego skryptu powoduje konieczność dodatkowego kodowania i wymaga pakowania/rozpakowywania parametrów. Aby uniknąć kopiowania i wklejania tego samego bloku kodu między podobnymi etapami skryptu, należy rozważyć "przetwarzanie potoków, które pozwala podzielić cały proces na osobne kroki najwyższego poziomu. Część z tych kroków może być współdzielona przez naprzemienne ścieżki. Jest to często wykorzystywane do przygotowywania parametrów i formatowania wyjścia. Pośredni wynik między etapami może być przechowywany w strukturze podrzędnej "parm".
Zamiast tego kodu:
|
Można rozważyć tę alternatywę:
|
Funkcje języka XPath 2
Motor skryptów w wersji 2 i wyższych obsługuje funkcje i operatory XQuery 1.0, a także standard XQuery 1.0 z niewielkimi ograniczeniami. Poniżej przedstawiono adresy URL do obu danych technicznych. Pierwsze łącze prowadzi do strony z funkcjami/operatorami XQuery, których można używać.
-
http://www.w3.org/TR/xpath-functions/
-
http://www.w3.org/TR/xquery/
Poniższe wyrażenia umożliwiają dostęp tylko do lokalnych systemów plików. (W przypadku innych protokołów, takich jak http, zwrócona zostanie pusta sekwencja):
-
fn:doc
-
fn:collection