Observações sobre o Mecanismo de Script a partir da Versão 2
Quando você escreve scripts usando a versão 2 do mecanismo, ou uma versão posterior, é preciso usar uma sintaxe extra para aproveitar a funcionalidade XPath 2. Em geral, todas as variáveis declaradas são consideradas strings. Isso significa que, se você quiser criar uma instrução matemática, será preciso declarar explicitamente o tipo de dados das variáveis como inteiros, números ou datas.
Cálculos de Data e Hora
Os tipos de dados de intervalo e data e hora da linguagem XPath aceitam operações aritméticas ('+', '-', '*' etc.) e funções, que podem ser usadas para cálculos de tempo da mesma forma que '1 + xs:integer(value)' é usado para cálculos numéricos.
Comparar duração:
if ("(xs:dateTime(fn:current-dateTime()) - xs:dateTime($updateDateTimeX))
ge xs:dayTimeDuration(concat('PT', BO/hoursBetweenStatisticsUpdate, 'H'))")
goto 60;
end-if;
Comparar uma data com outra:
if ("xs:date(parm/endDate) < xs:date(parm/startDate)")
terminate with error (11108, 11507 element='endDate');
end-if;
Comparar uma data com a data atual:
if ("xs:date(parm/startDate) <= xs:date($CURRENT-DATE)")
terminate with error (11108, 11507 element='endDate');
end-if;
Calcular o fim do mês:
// 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;
Comparando Datas/Horas no Formato de String
Os formatos de string semelhantes ao ISO mantêm a sequência AAAA MM DD HH MM SS, que é preenchida com zeros. Independentemente dos separadores, esse formato permanecerá adequado para operações de comparação. Em particular, é possível usar valores de data/hora no formato do Framework, “AAAA-MM-DD.HH.MM.SS”, com “=”, “!=”, além dos 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;
Convertendo Datas/Horas entre Framework e ISO
A conversão de data/hora do formato do Framework para o padrão ISO só é necessária para cálculos de data e hora. As comparações podem ser feitas diretamente com o formato do Framework. A única diferença entre o formato do Framework e os formatos de data/hora do padrão ISO são os separadores:
Framework: “AAAA-MM-DD.HH.MM.SS”
ISO: “YYYY-MM-DDTHH:MM:SS”
Exemplo de conversão do formato do Framework para o padrão ISO:
move "concat(substring($ouafDT, 1, 10), 'T', translate(substring($ouafDT, 12),'.',':'))" to $isoDT;
Exemplo de conversão do padrão ISO para o formato do Framework:
move "concat(substring($isoDT, 1, 10), '.', translate(substring($isoDT, 12),':','.'))" to $ouafDT;
Arredondamento de Dinheiro com Escala Dinâmica de Moeda
Como o número de casas decimais varia de acordo com a moeda em questão, é fornecida uma API para arredondar valores monetários com base na moeda informada.
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";
Aplicando Loop em Sequências
Em XPath 2, é possível organizar um loop durante uma sequência de inteiros, não apenas uma lista de nós.
Este exemplo mostra um loop durante um intervalo de meses. Ele é um construto de formação de sequência em XPath. A lista de nós XPath, com a qual já estamos familiarizados, é apenas outro tipo de sequência.
for ($month in "1 to 12")
Este exemplo mostra um loop durante um intervalo de anos em ordem decrescente:
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 exemplo mostra um loop em uma lista de nós usando 'index' para permitir acesso a outras listas de nós:
for ($idx in "1 to count(parm/touData/touList)")
move "parm/touData/touList[$idx]" to $tou; // access any list with this index
É possível usar a sintaxe acima como uma alternativa elegante à manutenção de índices separados, por exemplo, no lugar de:
move “0” to $idx;
for ($item in "parm/touData/touList")
move “1 + xs:integer($idx)” to $idx;
Preenchimento de String e Formatação Decimal
Esses recursos são usados com formatos específicos de entrada ou saída. São aplicados zeros, espaços e outros tipos de preenchimento.
Este exemplo mostra um caso de prefixação para componentes de data/hora, por exemplo, gerando “2010-01-02” em vez de “2010-1-2”.
move "substring(concat('0',string($month)), string-length(string($month)), 2)" to $mon2;
Este exemplo mostra um caso de sufixação para alinhamento por preenchimento com zeros, por exemplo, gerando “12,30” e “4,00” em vez de “12,3” e “4”. No exemplo, são realizadas 3 tarefas: arredondamento de 2 casas decimais, inclusão de um período (se necessário) e preenchimento com zeros.
// 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;
Operação Ternária
Esse tipo de operação faz uma escolha entre valores com base em uma condição, portanto, pode ser usado em uma expressão só, em vez de em um bloco de if/else. Ele é conhecido em C/C++ como ‘cond ? value1 : value2’ ou em BASIC como ‘IFF(cond, value1, value2)’. Em XPath, a sintaxe é: "if (cond) then value1 else value2". Note que ele não é o bloco superior da instrução if na escrita de script.
Em XPath, ele é uma expressão, que pode ser combinada com outras expressões. Em escrita de script, é possível usar a operação ternária como:
move "if (string(D1-UnitOfMeasure/measuresPeakQuantity) = 'D1MP') then 'D1MX' else 'D1SM' " to $func;
Processamento de Pipeline
Ao escrever scripts, não é fácil criar uma parte de código simples e reutilizável, pois não há funções locais, e a chamada de um script separado gera sobrecarga de codificação, além de exigir parâmetros de compactação/descompactação. Para não precisar copiar e colar um mesmo bloco de código entre estágios semelhantes do script, analise a possibilidade de criar um pipeline, ou seja, quebrar o processo geral em etapas separadas de nível superior, podendo compartilhar algumas delas entre caminhos alternativos. Isso é comum para preparação de parâmetro e formatação de saída. É possível armazenar um resultado intermediário entre estágios em uma subestrutura “parm”.
Em vez deste código:
|
Considere esta alternativa:
|
Funções de XPath 2
A versão 2 e as versões posteriores do mecanismo de script dão suporte a Funções e Operadores da linguagem XQuery 1.0, a qual padroniza a si mesma com algumas pequenas limitações. Veja a seguir URLs para ambas as especificações. O primeiro link tem funções/operadores disponíveis para uso na XQuery.
-
http://www.w3.org/TR/xpath-functions/
-
http://www.w3.org/TR/xquery/
Os próximos links só acessam sistemas de arquivos locais. (Para outros protocolos, como http, eles retornarão uma sequência em branco.)
-
fn:doc
-
fn:collection