tengo un problema al manejar las fechas en XPath, a ver si alguien me puede ayudar...
Tengo el siguiente XML (ejemplo) que contiene fechas con formato \'YYYYMMDD\', de las cuales tengo que seleccionar la mayor y calcular la diferencia hasta la fecha actual (fechaActual-fechaMayor):
<xml>
<fecha>20100215</fecha>
<fecha>20050522</fecha>
<fecha>20010215</fecha>
<fecha>20091231</fecha>
</xml>
La fecha mayor la consigo con la funcion: "max(//fecha)", pero eso me da un valor numérico (double) que tengo restar a la fecha actual ("current-date()").
¿Alguien sabe como se puede hacer eso?
Saludo.
Hola,
Tienes suerte con el formato YYYYMMDD: al ir de mayor a menor granularidad (año, mes, día), ese formato se ordena correctamente tanto si lo comparas como texto como si lo comparas como número. Eso simplifica mucho encontrar la fecha máxima, ni siquiera hace falta convertirla a un tipo fecha real:
<xsl:template match="/">
<xsl:variable name="fechas" select="//fecha"/>
<xsl:for-each select="$fechas">
<xsl:sort select="." order="descending" data-type="text"/>
<xsl:if test="position()=1">
Fecha mayor: <xsl:value-of select="."/>
</xsl:if>
</xsl:for-each>
</xsl:template>
Ordenando como texto descendente y quedándote con la primera posición, obtienes la fecha más reciente sin necesidad de parsear nada.
Ahora, la parte complicada: la diferencia de días hasta hoy. Ahí el problema es que estás en XSLT 1.0/XPath 1.0, que no tiene funciones de aritmética de fechas de serie (eso llegó con XPath 2.0). Tienes dos caminos:
1. Si tu procesador XSLT soporta XSLT 2.0 (por ejemplo Saxon, que es el más habitual fuera del navegador), la resta de fechas es directa:
<xsl:variable name="fechaMayor" select="xs:date(concat(substring($fecha,1,4),'-',substring($fecha,5,2),'-',substring($fecha,7,2)))"/>
<xsl:variable name="dias" select="days-from-duration(current-date() - $fechaMayor)"/>
2. Si estás limitado a XSLT 1.0 (por ejemplo, transformación en el navegador con el motor nativo), no hay una función de resta de fechas fiable sin escribir tú mismo el cálculo del día juliano a mano, lo cual es bastante tedioso. En ese caso, mi recomendación real es no forzar el cálculo dentro del XSLT: deja que el XSLT te devuelva la fecha máxima ya extraída (como en el ejemplo de arriba), y calcula la diferencia de días en el lenguaje que esté consumiendo el resultado (JavaScript, PHP, lo que sea), donde sí tienes funciones de fecha nativas y fiables.
David Carrero
