Domanda

Ho avuto difficoltà a trovare buoni modi per prendere un formato orario e determinare facilmente se è valido quindi produrre un elemento risultante che ha una formattazione usando XSLT 1.0.

Dato il seguente xml:

<root>
    <srcTime>2300</srcTime>
</root>

Sarebbe bello produrre l'xml risultante:

<root>
    <dstTime>23:00</dstTime>
</root>

Tuttavia, se l'xml di origine contiene un formato orario di 24 ore non valido, l'elemento dstTime risultante dovrebbe essere vuoto.

Ad esempio, quando il codice sorgente XML non valido è il seguente:

<root>
    <srcTime>NOON</srcTime>
</root>

L'xml risultante dovrebbe essere:

<root>
    <dstTime></dstTime>
</root>

La domanda è: qual è il miglior XSLT 1.0 che potrebbe essere scritto per produrre i risultati desiderati? La speranza sarebbe quella di mantenerlo abbastanza semplice e di non dover analizzare ogni parte del tempo (vale a dire che la corrispondenza del modello sarebbe dolce se possibile).

È stato utile?

Soluzione

Non ci sono espressioni regolari in XSLT 1.0, quindi temo che la corrispondenza dei pattern non sia possibile.

Non sono chiaro se <srcTime>23:00</srcTime> dovrebbe essere legale o no? Se lo è, prova:

<dstTime>
  <xsl:if test="string-length(srcTime) = 4 or
                string-length(srcTime) = 5">
    <xsl:variable name="hour" select="substring(srcTime, 1, 2)" />
    <xsl:if test="$hour >= 0 and 24 > $hour">
      <xsl:variable name="minute">
        <xsl:choose>
          <xsl:when test="string-length(srcTime) = 5 and
                          substring(srcTime, 3, 1) = ':'">
            <xsl:value-of select="substring(srcTime, 4, 2)" />
          </xsl:when>
          <xsl:when test="string-length(srcTime) = 4">
            <xsl:value-of select="substring(srcTime, 3, 2)" />
          </xsl:when>
        </xsl:choose>
      </xsl:variable>
      <xsl:if test="$minute >= 0 and 60 > $minute">
        <xsl:value-of select="concat($hour, ':', $minute)" />
      </xsl:if>
    </xsl:if>
  </xsl:if>
</dstTime>

In caso contrario, e quattro cifre è l'unica cosa legale quindi:

<dstTime>
  <xsl:if test="string-length(srcTime) = 4">
    <xsl:variable name="hour" select="substring(srcTime, 1, 2)" />
    <xsl:if test="$hour >= 0 and 24 > $hour">
      <xsl:variable name="minute" select="substring(srcTime, 3, 2)" />
      <xsl:if test="$minute >= 0 and 60 > $minute">
        <xsl:value-of select="concat($hour, ':', $minute)" />
      </xsl:if>
    </xsl:if>
  </xsl:if>
</dstTime>

Altri suggerimenti

XSLT 1.0 non ha alcun supporto standard per la manipolazione di data / ora.

Devi scrivere una semplice funzione di analisi e formattazione. Non sarà semplice e non sarà carino.

XSLT è davvero progettato per le trasformazioni degli alberi. Questo tipo di manipolazione dei nodi di testo viene eseguita al di fuori di XSLT.

A seconda dell'effettivo processore xslt utilizzato potresti essere in grado di eseguire le operazioni desiderate nella funzione di estensione personalizzata (che dovresti fare da solo).

Xalan offre un buon supporto per le funzioni di estensione , non puoi scriverle solo in Java ma anche in JavaScript o in altre lingue supportate da Apache BSF .

Il motore XSLT di Microsoft supporta anche estensioni personalizzate, come descritto in .NET Framework Guida per gli sviluppatori, estensione dei fogli di stile XSLT

Dai un'occhiata a: http://www.exslt.org/ in particolare la " date e orari " sezione. Non ci ho scavato in profondità, ma sembra che potrebbe essere quello che stai cercando.

Anche la funzione time () exslt.org non ti aiuterà qui, perché si aspetta che il suo input sia nel formato corretto (xs: dateTime o xs: time).

Questo è qualcosa che è meglio risolto al di fuori di XSLT. Lo dico come qualcuno che usa abitualmente XSLT per fare cose per le quali non è stato progettato e riesce a far funzionare le cose. Era davvero non progettato per analizzare le stringhe.

La soluzione ideale è quella di riparare qualunque cosa stia producendo il documento XML in modo che formatta i tempi usando lo standard internazionale convenientemente stabilito proprio per quello scopo, usando il principio che non dovresti persistere o trasmettere dati di merda se puoi evitare di farlo .

Ma se ciò non fosse possibile, dovresti correggere i dati prima di passarli a XSLT o correggerli dopo aver generato l'output della trasformazione.

E per completare l'elenco, c'è anche Modulo di elaborazione data / ora parte della libreria standard XSLT di Steve Ball.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top