Um XSLT pode inserir a data atual?

92

Um programa que usamos em meu escritório exporta relatórios traduzindo um arquivo XML que exporta com um arquivo XSLT para XHTML. Estou reescrevendo o XSLT para alterar a formatação e adicionar mais informações do arquivo XML de origem.

Gostaria de incluir a data de criação do arquivo no relatório final. Mas a data / hora atual não está incluída no arquivo XML original, nem tenho qualquer controle sobre como o arquivo XML é criado. Não parece haver nenhuma função de data construída em XSLT que retornará a data atual.

Alguém tem alguma ideia de como posso incluir a data atual durante minha transformação XSLT?

Eric Anastas
fonte
Não sei qual analisador está sendo usado, esse é o problema. O programa que usei exporta relatórios diretamente e usa o arquivo XSLT em seu diretório de programa para gerar os relatórios.
Eric Anastas,

Respostas:

115

XSLT 2

As funções de data estão disponíveis nativamente, como:

<xsl:value-of  select="current-dateTime()"/>

Também existe current-date()e current-time().

XSLT 1

Use o pacote EXSLT de extensão de data e hora.

  1. Baixe o pacote de data e hora do GitHub .
  2. Extraia date.xslpara o local de seus arquivos XSL.
  3. Defina o cabeçalho da folha de estilo.
  4. Importar date.xsl.

Por exemplo:

<xsl:stylesheet version="1.0" 
    xmlns:date="http://exslt.org/dates-and-times" 
    extension-element-prefixes="date"
    ...>

    <xsl:import href="date.xsl" />

    <xsl:template match="//root">
       <xsl:value-of select="date:date-time()"/>
    </xsl:template>
</xsl:stylesheet>

Jim Garrison
fonte
7
Para quem usa .net / c # , não perca muito tempo tentando fazer com que as importações EXSLT funcionem com os transformadores .NET XSLT padrão - use MVP.XML imediatamente. Possui suporte integrado para ESXLT .
Joel Purra
14

Para o analisador MSXML, tente isto:

<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:msxsl="urn:schemas-microsoft-com:xslt"
                xmlns:my="urn:sample" extension-element-prefixes="msxml">

    <msxsl:script language="JScript" implements-prefix="my">
       function today()
       {
          return new Date(); 
       } 
    </msxsl:script> 
    <xsl:template match="/">

        Today = <xsl:value-of select="my:today()"/>

    </xsl:template> 
</xsl:stylesheet>

Leia também Scripts de folha de estilo XSLT usando msxsl: script e Extending XSLT com JScript, C # e Visual Basic .NET

Rubens Farias
fonte
Isso não funciona com o Apache FOP como transformador. Mensagem de erro: a chamada do método de instância para o método hoje requer uma instância de Object como primeiro argumento
Trey Carroll
1
oops: extension-element-prefixes = "msxml" deve ser extension-element-prefixes = "msxsl". Também não funciona no meu sistema.
Jay
14

Você tem controle sobre a execução da transformação? Nesse caso, você poderia passar a data atual para o XSL e usar $ current-date de dentro de seu XSL. Abaixo está como você declara o parâmetro de entrada, mas sabendo como você está executando a transformação, não posso dizer como passar o valor.

<xsl:param name="current-date" />

Por exemplo, no script bash, use:

xsltproc --stringparam current-date `date +%Y-%m-%d` -o output.html path-to.xsl path-to.xml

Então, no xsl você pode usar:

<xsl:value-of select="$current-date"/>
Kevin Hakanson
fonte
1
Na verdade, como passar o valor depende do sistema. Uma possível opção: com xsltproc em UNIX, pode ser: xsltproc --stringparam current-date `date +%Y-%m-%d` -o output.html path-to.xsl path-to.xml. Alguns sistemas também aceitam parâmetros como $param=value, então, nesse caso, em $current-date=`date +%Y-%m-%d`algum lugar. Ou procure maneiras de especificar parâmetros em qualquer processador XSLT que você esteja usando.
lindes
10
...
    xmlns:msxsl="urn:schemas-microsoft-com:xslt"
    xmlns:local="urn:local" extension-element-prefixes="msxsl">

    <msxsl:script language="CSharp" implements-prefix="local">
        public string dateTimeNow()
        {       
          return DateTime.Now.ToString("yyyy-MM-ddTHH:mm:ssZ"); 
        } 
    </msxsl:script>  
...
    <xsl:value-of select="local:dateTimeNow()"/>
Evgeny Glazov
fonte
7

Resposta tardia, mas minha solução funciona em Eclipse XSLT. O Eclipse usa XSLT 1 no momento em que este artigo foi escrito. Você pode instalar um motor XSLT 2 como o Saxon. Ou você pode usar a solução XSLT 1 abaixo para inserir a data e a hora atuais.

<xsl:value-of select="java:util.Date.new()"/>

Isso chamará a classe Data do Java para gerar a data. Não funcionará a menos que você também coloque a seguinte definição "java:" em sua <xsl:stylesheet>tag.

<xsl:stylesheet [...snip...]
         xmlns:java="java"
         [...snip...]>

Espero que ajude alguém. Essa resposta simples foi difícil de encontrar para mim.

Mark Hamby
fonte
6
format-date(current-date(), '[M01]/[D01]/[Y0001]') = 09/19/2013
format-time(current-time(), '[H01]:[m01] [z]') = 09:26 GMT+10
format-dateTime(current-dateTime(), '[h1]:[m01] [P] on [MNn] [D].') = 9:26 a.m. on September 19.

referência: Formatação de datas e horas usando XSLT 2.0 e XPath

Preto
fonte