ملاحظات حول إصدار محرك السكريبت 2 والإصدارات الأحدث

تتطلب كتابة السكريبت باستخدام إصدار المحرك 2 أو أحدث بعض الصياغة الإضافية للاستفادة من وظيفة المسار X 2. بشكل عام، سيتم افتراض أن أي متغير محدد سيكون سلسلة. يعني ذلك، أنه إذا كنت تنوي إنشاء عبارة رياضية سيكون إذًا من الضروري تحديد نوع بيانات المتغيرات بشكل واضح كالأعداد الصحيحة أو الأعداد أو التواريخ.

ملاحظة: ما لم يلاحظ خلاف ذلك، كل أمثلة المسار X في هذا الموضوع هي لمحرك الإصدار 1 - مما يعني المسار X 1. ليس بالضرورة أن تعمل العبارات باستخدام المسار X 1 باستخدام المسار X 2. ويكون ذلك صحيحًا فيما يتعلق بتنفيذ الرياضيات، راجع الأمثلة المذكورة أدناه.

حساب التاريخ والوقت

يدعم تاريخ/وقت المسار X وأنواع بيانات الفترة الزمنية العمليات الحسابية ('+'، '-'، '*' إلخ.) والدالات، التي يمكن استخدامها لعمليات احتساب الوقت بنفس طريقة '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;
ملاحظة: تستخدم صِيغ التاريخ/الوقت/الفترة الزمنية للمسار X معيار 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";

التكرار عبر التسلسلات

في المسار X 2 من الممكن تنظيم حلقة for عبر تسلسل الأرقام الصحيحة، ليس قائمة عُقد فقط.

يعرض هذا المثال حلقة عبر مدى الشهور. هذه هي بنية تشكيل تسلسل في المسار X. قائمة عُقد المسار X، المألوفة بالنسبة لنا، هي مجرد نوع آخر من التسلسل.

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; 

يعرض هذا المثال إلحاق لاحقة لإضافة محاذاة ملء بالقيمة 0 للخانة العشرية، على سبيل المثال إنتاج “12.30” و“4.00” بدلاً من “12.3” و“4”. ينفذ المثال 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. وهي معروفة في C/C++ على أنها ‘cond ? value1 : value2’ أو في BASIC على أنها ‘IFF(cond, value1, value2)’. في المسار X تكون الصياغة هي: "if (cond) then value1 else value2". لاحظ أن هذه ليست كتلة برمجية من عبارات if على أعلى مستوى لكتابة السكريبت.

في المسار X هذا هو تعبير، يمكن جمعه مع التعبيرات الأخرى. في كتابة السكريبت يمكن استخدامه في:

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

المعالجة المتوازية

في كتابة السكريبت، ليس من السهل إنشاء جزء من رمز بسيط وقابل للاستخدام مرة أخرى نظرًا لعدم وجود دالات داخلية، كما يعتبر استدعاء سكريبت منفصل عبئًا على التشفير كما يتطلب معلمات التعبئة/التفريغ. لتجنب نسخ ولصق نفس الكتلة البرمجية للرموز بين مراحل السكريبت المشابهة، فكر في استخدام ‘المعالجة المتوازية’، التي تقوم بتقسيم العملية الإجمالية إلى خطوات منفصلة على أعلى مستوى، يمكن مشاركة بعض منها بين المسارات البديلة. هذا أمر شائع لتجهيز المعلمة وتنسيق المخرجات. ‏‏يمكن تخزين نتيجة وسيطة بين المراحل في هيكل فرعي "معلمة".

بدلاً من هذا الرمز

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 ...

دالات المسار X 2

تدعم إصدارات محرك السكريبت 2 والإصدارات الأحدث الدالات والمعاملات ومعيار XQuery 1.0 نفسه مع بعض الحدود الصغيرة. فيما يلي عناوين URL لكل من المواصفات. الارتباط الأول يحتوي على الدالات/المعاملات المتاحة للاستخدام من XQuery.

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

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

يمكن للعناصر التالية الوصول إلى أنظمة الملفات المحلية. (بالنسبة للبروتوكولات الأخرى مثل http فإنها سوف ينتج عنها تسلسل فارغ):

  • fn:doc

  • fn:collection