2012-10-01 19 views
7

Mi modelo de datos es el siguiente:Obtener la fecha más reciente en registros XML

<Club> 
<Captain> 
<Name></Name> 
<DateOfBirth>15-01-1985</DateOfBirth> 
</Captain> 
<PlayingStaff> 
<Player> 
<DateOfBirth>14-01-1993</DateOfBirth> 
</Player> 
<Player> 
<DateOfBirth>07-12-1975</DateOfBirth> 
</Player> 
<Player> 
<DateOfBirth>11-11-1991</DateOfBirth> 
</Player> 
</PlayingStaff> 
</Club> 

He intentado usar la respuesta dada aquí: XSLT: Getting the latest date pero ¿no es cierto me da ningún valor.

Estoy intentando que el jugador más joven pase a una función externa.

que estoy haciendo esto en Biztalk por lo que tienen que atenerse a XSLT1

Mi trabajo hasta ahora es la siguiente:

<xsl:variable name="youngestPlayer"> 
      <xsl:for-each select="$ClubRoot/*[local-name()='PlayingStaff']/*[local-name()='Player']"> 
       <xsl:sort select="./*[local-name()='DateOfBirth']" order="descending"/> 
       <xsl:if test="position() = 1"> 
        <xsl:value-of select="DateOfBirth"/> 
       </xsl:if> 
      </xsl:for-each> 
     </xsl:variable> 
     <xsl:variable name="IsYoungestPlayerUnderAgeLimit" select="externalfunctionreturningboolean"> 
      <xsl:element name="blahhh"><xsl:value-of select="$IsYoungestPlayerUnderAgeLimit"/></xsl:element> 
      <xsl:element name="blahhh"><xsl:value-of select="$youngestPlayer"/></xsl:element> 

Esto es parte de una plantilla grande - en realidad no puedo cambiar esto, pero el valor de Clubroot es "<xsl:variable name="ClubRoot" select="/*[1]"/>" para asegurar que puedo leer sus nodos secundarios.

siempre estoy

<blahhh>false</blahhh> 
<blahhh/> 

como mis valores de depuración ... así que no estoy recogiendo el valor que espero

¿Alguien puede resaltar dónde me he equivocado?

A partir de los datos anteriores, esperaría el valor de 14-01-1993 en la variable del jugador más joven. Pero está en blanco.

Respuesta

6

El problema es que XSLT1.0 no tiene realmente el concepto de fechas, por lo que está ordenando efectivamente por los DateOfBirth elementos como si fueran cadenas simplemente normales. Si usted puede estar seguro de las fechas siempre vienen en el formato DD-MM-AAAA podría utilizar la manipulación de cadenas para ordenar por año, mes y día

<xsl:sort select="number(substring(DateOfBirth, 7, 4))" order="descending"/> 
<xsl:sort select="number(substring(DateOfBirth, 3, 2))" order="descending"/> 
<xsl:sort select="number(substring(DateOfBirth, 1, 2))" order="descending"/> 

Por lo tanto, teniendo en cuenta lo siguiente XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="xml" indent="yes"/> 
    <xsl:template match="/Club"> 
     <xsl:for-each select="PlayingStaff/Player"> 
     <xsl:sort select="number(substring(DateOfBirth, 7, 4))" order="descending"/> 
     <xsl:sort select="number(substring(DateOfBirth, 3, 2))" order="descending"/> 
     <xsl:sort select="number(substring(DateOfBirth, 1, 2))" order="descending"/> 

     <xsl:if test="position() = 1"> 
      <xsl:value-of select="DateOfBirth"/> 
     </xsl:if> 
     </xsl:for-each> 
    </xsl:template> 
</xsl:stylesheet> 

Cuando se aplica a XML, el siguiente es resultado de

14-01-1993 
+2

Al usar la función translate(), se puede reducir el número de xsl: sort instrucciones de 3 a 1, Y simplifique la expresión 'xsl: sort/@ select'. –

1

la razón por la fecha de clasificación en su referencia vinculada 'trabajó' era porque estaba en yyyy-MM-dd formato, en contraposición a y nuestro formato dd-MM-yyyy.

Una alternativa a la propuesta de Tim C/Sean es utilizar las funciones de script C# (ya que está utilizando BizTalk) para revertir la fecha a una ordenable según su enlace, pero tenga en cuenta que es poco probable que sea tan xslt funciones. Tenga en cuenta también que puede necesitar usar msxsl:node-set en sus variables para decirle al analizador de BizTalk que se trata de un fragmento.

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
       xmlns:userCSharp="http://schemas.microsoft.com/BizTalk/2003/userCSharp" 
       xmlns:msxsl="urn:schemas-microsoft-com:xslt" 
       exclude-result-prefixes="userCSharp msxsl" 
       > 
    <xsl:output method="xml" indent="yes"/> 

    <xsl:template match="/"> 
     <xsl:variable name="ClubRoot" select="/*[1]"/> 
     <xsl:variable name="orderedPlayers"> 
      <xsl:for-each select="msxsl:node-set($ClubRoot)/*[local-name()='PlayingStaff']/*[local-name()='Player']"> 
       <xsl:sort select="userCSharp:makeSortableDate(string(*[local-name()='DateOfBirth']), 'dd-MM-yyyy')" order="descending"/> 
       <xsl:copy-of select="node() | @*"/> 
      </xsl:for-each> 
     </xsl:variable> 

     <xsl:variable name="youngestPlayerDOB"> 
      <xsl:value-of select="msxsl:node-set($orderedPlayers)[1]/DateOfBirth/text()" /> 
     </xsl:variable> 

     <xsl:element name="blahhh"> 
      <xsl:variable name="IsYoungestPlayerUnderAgeLimit" select="userCSharp:externalfunctionreturningboolean($youngestPlayerDOB)" /> 
      <xsl:value-of select="$IsYoungestPlayerUnderAgeLimit"/> 
     </xsl:element> 
     <xsl:element name="blahhh"> 
      <xsl:value-of select="$youngestPlayerDOB"/> 
     </xsl:element> 
    </xsl:template> 

    <msxsl:script language="C#" implements-prefix="userCSharp"> 
     <![CDATA[ 
     public System.String makeSortableDate(System.String yourDate, string format) 
     { 
      return (System.DateTime.ParseExact(yourDate, format, System.Globalization.CultureInfo.InvariantCulture).ToString("yyyy-MM-dd")); 
     } 

     public bool externalfunctionreturningboolean(System.String dobString) 
     { 
      System.DateTime someDate; 
      if (System.DateTime.TryParse(dobString, out someDate)) 
      { 
       // NB : Doesn't work out leap years correctly! 
       if ((System.DateTime.Now - someDate).Days < 21 * 365.25) 
       { 
        return true; 
       } 
      } 
      return false; 
     } 
    ]]> 
    </msxsl:script> 

</xsl:stylesheet> 

que he tomado un corte en la función y supuso que el límite menor de edad es de 21. Los rendimientos por encima

<blahhh>true</blahhh> 
<blahhh>14-01-1993</blahhh> 
Cuestiones relacionadas