Notas de la versión de motor de scripts 2 y posteriores
Los scripts que usan el motor de la versión 2 o posterior necesitan sintaxis adicional para aprovechar la funcionalidad de XPath 2. En general, se asumirá que cualquier variable declarada es una cadena. Esto significa que, si tiene previsto crear una sentencia matemática, es necesario declarar de forma explícita el tipo de datos de las variables como números enteros, números o fechas.
Aritmética de fecha y hora
Los tipos de datos de fecha y hora y de intervalo de XPath soportan operaciones ('+', '-', '*', etcétera) y funciones aritméticas que pueden usarse para realizar cálculos de tiempo de la misma forma que '1 + xs:integer(valor)' se utiliza para realizar cálculos numéricos.
Comparar duración:
if ("(xs:dateTime(fn:current-dateTime()) - xs:dateTime($updateDateTimeX))
ge xs:dayTimeDuration(concat('PT', BO/hoursBetweenStatisticsUpdate, 'H'))")
goto 60;
end-if;
Comparar una fecha con otra:
if ("xs:date(parm/endDate) < xs:date(parm/startDate)")
terminate with error (11108, 11507 element='endDate');
end-if;
Comparar una fecha con la fecha de hoy:
if ("xs:date(parm/startDate) <= xs:date($CURRENT-DATE)")
terminate with error (11108, 11507 element='endDate');
end-if;
Calcular el final de mes:
// 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;
Comparaciones de fecha y hora en formato de cadena
Todos los formatos de cadena similares al formato ISO de fecha y hora mantiene la secuencia AAAA MM DD HH MM SS, que se rellena con ceros. Con independencia de los separadores, este formato seguirá siendo adecuado para las operaciones de comparación. En concreto, los valores de fecha y hora del formato de marco “AAAA-MM-DD.HH.MM.SS” se puede usar con “=”, “!=”, y también con los operadores “>”, “>=”, “<”, “<=”.
// 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;
Conversiones de fecha y hora entre el marco e ISO
La conversión de fecha y hora del formato de marco a ISO solo es necesaria para la aritmética de fecha y hora. Las comparaciones se pueden hacer de forma directa con el formato de marco. La única diferencia entre el formato de marco y los formatos de fecha/hora ISO se encuentra en los separadores:
Marco: “AAAA-MM-DD.HH.MM.SS”
ISO: “AAAA-MM-DDTHH:MM:SS”
Ejemplo de conversión del formato de marco a ISO:
move "concat(substring($ouafDT, 1, 10), 'T', translate(substring($ouafDT, 12),'.',':'))" to $isoDT;
Ejemplo de conversión de ISO al formato de marco:
move "concat(substring($isoDT, 1, 10), '.', translate(substring($isoDT, 12),':','.'))" to $ouafDT;
Redondear importes monetarios con una escala de divisas dinámica
Debido a que diversas divisas soportan un número distinto de decimales, el marco proporciona una API para redondear importes monetarios según una divisa determinada.
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";
Bucles en secuencias
En XPath 2 es posible organizar un bucle para una secuencia de números enteros, no solo una lista de nodos.
En este ejemplo se muestra un bucle en un rango de meses. Esta es una estructura de formación de secuencia en XPath. La lista de nodos de XPath, con la que está familiarizado, es solo otro tipo de secuencia.
for ($month in "1 to 12")
Este ejemplo muestra un bucle en un rango de años determinado en orden descendente:
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;
...
Este ejemplo muestra un bucle en una lista de nodos en la que se usa 'index' para que se pueda acceder a otras listas de nodos:
for ($idx in "1 to count(parm/touData/touList)")
move "parm/touData/touList[$idx]" to $tou; // access any list with this index
La sintaxis anterior se puede usar como una alternativa elegante para el mantenimiento de índices de forma separada, en lugar del ejemplo siguiente:
move “0” to $idx;
for ($item in "parm/touData/touList")
move “1 + xs:integer($idx)” to $idx;
Relleno de cadenas y formato decimal
Se utiliza para formatos de entrada específicos o formatos de salida. Es aplicable a ceros, espacios y otros tipos de relleno.
En este ejemplo se muestra la inclusión de prefijos a los componentes de fecha/hora (por ejemplo, para que el resultado sea “2010-01-02” en lugar de “2010-1-2”).
move "substring(concat('0',string($month)), string-length(string($month)), 2)" to $mon2;
En este ejemplo se muestra la inclusión de sufijos para añadir una alineación decimal rellenada con ceros (por ejemplo, para que los resultados sean “12.30” y “4.00” en lugar de “12.3” y “4”). En el ejemplo se realizan 3 tareas: redondear a 2 decimales, insertar un punto si es necesario y rellenar con ceros.
// 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;
Operación ternaria
Realiza una elección entre valores basados en una condición para que pueda usarse en una sola expresión en lugar de en un bloque if/else. La sintaxis en C/C++ sería ‘condición ? valor1 : valor2’ y en BASIC sería ‘IFF(condición, valor1, valor2)’. En XPath la sintaxis es: "if (condición) then valor1 else valor2". Tenga en cuenta que este no es el bloque de sentencias "if" de scripts de nivel superior.
En XPath esto es una expresión que se puede combinar con otras expresiones. En la generación de scripts se puede usar como:
move "if (string(D1-UnitOfMeasure/measuresPeakQuantity) = 'D1MP') then 'D1MX' else 'D1SM' " to $func;
Proceso de pipeline
En la generación de scripts no resulta fácil crear una porción de código reutilizable que sea simple, ya que no hay funciones locales, y una llamada a script independiente supone un exceso de codificación y requiere parámetros de empaquetado/desempaquetado. Para evitar tener que copiar y pegar el mismo bloque de código en etapas de script similares, considere usar el "pipelining", que divide el proceso general en pasos de nivel superior independientes, algunos de los cuales pueden compartirse entre rutas alternas. Esto es habitual en la preparación de parámetros y en los formatos de salida. Un resultado intermedio entre etapas puede almacenarse en una subestructura de “parámetros”.
En lugar de este código:
|
Considere esta alternativa:
|
Funciones de XPath 2
Las versiones 2 y posteriores del motor de scripts soportan las funciones y operadores de XQuery 1.0 y el propio estándar XQuery 1.0 con algunas limitaciones menores. A continuación se muestran las URL de ambas especificaciones. En el primer enlace se encuentran las funciones y operadores disponibles para usar desde XQuery.
-
http://www.w3.org/TR/xpath-functions/
-
http://www.w3.org/TR/xquery/
Mediante la siguiente función solo puede acceder a los sistemas de ficheros locales. Para otros protocolos (por ejemplo, http) se devolverá una secuencia vacía:
-
fn:doc
-
fn:collection