2009-07-29 6 views
5

Pregunta bastante simple, ¿cómo puedo transformar un número (1, 2, 3, etc.) en un número ordinal fácil de imprimir (1º, 2º, 3º, etc.) usando xslt?Cómo transformar un número (1,2,3, etc.) en un número ordinal (1º, 2º, 3º, etc.) usando xslt

Actualmente las siguientes obras de 1-20, pero que podríamos estar viendo grandes conjuntos de entidades conseguir el puesto pronto:

<xsl:template name="FormatRanking"> 
    <xsl:param name="Value"></xsl:param> 

    <xsl:choose> 
     <xsl:when test="$Value = '1'"> 
      <xsl:value-of select="$Value"/>st 
     </xsl:when> 
     <xsl:when test="$Value = '2'"> 
      <xsl:value-of select="$Value"/>nd 
     </xsl:when> 
     <xsl:when test="$Value = '3'"> 
      <xsl:value-of select="$Value"/>rd 
     </xsl:when> 
     <xsl:otherwise> 
      <xsl:value-of select="$Value"/>th 
     </xsl:otherwise> 
    </xsl:choose> 

</xsl:template> 

La única manera me gustaría saber cómo hacer esto sería cambiar el XSL: cuando de :

<xsl:when test="$Value = '1'"> 
<xsl:when test="$Value = '2'"> 
<xsl:when test="$Value = '3'"> 

a (ni siquiera estoy seguro si esto es correcto):

<xsl:when test="$Value = '1' or $Value = '21' or $Value = '31' ..."> 
<xsl:when test="$Value = '2' or $Value = '22' or $Value = '33' ..."> 
<xsl:when test="$Value = '3' or $Value = '22' or $Value = '33' ..."> 

me gustaría hacerlo Mething similar a este Is there an easy way to create ordinals in C#? pero no estoy seguro de si es posible en Xslt.

En este punto, solo necesitamos una solución en inglés.

+2

Tu fe en las habilidades de XSLT es conmovedora, si no es realista – skaffman

+1

@skaffman: Supongo que estás subestimando las capacidades de XSLT. – Tomalak

+0

Después de todo, XSLT supuestamente está completo. – Eric

Respuesta

9

Aquí está la solución de "Is there an easy way to create ordinals in C#?", traducido a XSLT:

<xsl:template name="FormatRanking"> 
    <xsl:param name="Value" select="0" /> 

    <xsl:value-of select="$Value"/> 

    <!-- a little parameter sanity check (integer > 0) --> 
    <xsl:if test=" 
    translate($Value, '', '') = '' 
    and 
    $Value > 0 
    "> 
    <xsl:variable name="mod100" select="$Value mod 100" /> 
    <xsl:variable name="mod10" select="$Value mod 10" /> 

    <xsl:choose> 
     <xsl:when test="$mod100 = 11 or $mod100 = 12 or $mod100 = 13">th</xsl:when> 
     <xsl:when test="$mod10 = 1">st</xsl:when> 
     <xsl:when test="$mod10 = 2">nd</xsl:when> 
     <xsl:when test="$mod10 = 3">rd</xsl:when> 
     <xsl:otherwise>th</xsl:otherwise> 
    </xsl:choose> 
    </xsl:if> 
</xsl:template> 
+0

¡Gracias Tomalak, esto es exactamente lo que necesito! –

+0

@Tomalak Muchas gracias! Esto es algo que he estado buscando. Eres un genio :) – DashaLuna

0

¿Podría usar una extensión XSLT? Sé que EXSLT tiene un amplio rango de date and time extensions.

+0

Ni siquiera estoy seguro de qué es una extensión XSLT y no tengo tiempo ahora para analizar eso, gracias por la sugerencia. Haré una nota para investigarlo más tarde. –

+0

@Dan He estado buscando extensiones de fecha y hora EXSLT, no parece que tengan una solución/extensión para esta tarea. – DashaLuna

5

No estoy diciendo que es una buena idea hacer esto en XSLT, pero ...

<xsl:template name="FormatRanking"> 
    <xsl:param name="Value"></xsl:param> 

    <xsl:choose> 
      <xsl:when test="substring($Value,string-length($Value)-1) = '11'"> 
        <xsl:value-of select="$Value"/>th 
      </xsl:when> 
      <xsl:when test="substring($Value,string-length($Value)-1) = '12'"> 
        <xsl:value-of select="$Value"/>th 
      </xsl:when> 
      <xsl:when test="substring($Value,string-length($Value)-1) = '13'"> 
        <xsl:value-of select="$Value"/>th 
      </xsl:when> 
      <xsl:when test="substring($Value,string-length($Value)) = '1'"> 
        <xsl:value-of select="$Value"/>st 
      </xsl:when> 
      <xsl:when test="substring($Value,string-length($Value)) = '2'"> 
        <xsl:value-of select="$Value"/>nd 
      </xsl:when> 
      <xsl:when test="substring($Value,string-length($Value)) = '3'"> 
        <xsl:value-of select="$Value"/>rd 
      </xsl:when> 
      <xsl:otherwise> 
        <xsl:value-of select="$Value"/>th 
      </xsl:otherwise> 
    </xsl:choose> 
    </xsl:template> 

Editar: o un poco más ordenado solución:

<xsl:template name="FormatRanking"> 
    <xsl:param name="Value"></xsl:param> 

    <xsl:variable name="penultimateChar" select="substring($Value,string-length($Value)-1, 1)"/> 
    <xsl:variable name="lastChar" select="substring($Value,string-length($Value))"/> 

    <xsl:value-of select="$Value"/> 
    <xsl:choose> 
      <xsl:when test="$penultimateChar= '1'"> 
        <xsl:text>th </xsl:text> 
      </xsl:when> 
      <xsl:when test="$lastChar = '1'"> 
        <xsl:text>st </xsl:text> 
      </xsl:when> 
      <xsl:when test="$lastChar = '2'"> 
        <xsl:text>nd </xsl:text> 
      </xsl:when> 
      <xsl:when test="$lastChar = '3'"> 
        <xsl:text>rd </xsl:text> 
      </xsl:when> 
      <xsl:otherwise> 
        <xsl:text>th </xsl:text> 
      </xsl:otherwise> 
    </xsl:choose> 

+0

+1 para la solución n. ° 2, esto está bastante cerca. Sin embargo, me abstendría de aplicar funciones de cadena a los números, siempre que haya una manera de hacerlo con las funciones numéricas. – Tomalak

+0

Sí. buen punto. – Alohci

+0

Gracias por las sugerencias de Alohci, originalmente estaba pensando en hacer algo así como la solución n. ° 2, pero no sabía qué funciones de cadena usar. Sin embargo, voy con la solución de Tomalak que refleja la idea de C# y utiliza las matemáticas para hacerlo en lugar de las funciones de cadena. –

Cuestiones relacionadas