2009-01-28 10 views
5

J'essaye de transformer un datetime en un format de date aaaa-MM-jj, parce que j'utilise l'outil xsd.exe les types de données xs: date sont automatiquement changés en un datatype datetime, parce qu'il n'y a aucun type dans le .NET Framework qui correspond au type xs: date complètement.XSLT transformation datetime au format date

Mais je ne peux pas le faire fonctionner

<articles> 
     <article> 
      <articleid>48992</articleid> 
      <deliverydateasked>2009-01-29T00:00:00+01:00</deliverydateasked> 
     </article> 
     <article> 
      <articleid>48993</articleid> 
      <deliverydateasked>2009-01-30T00:00:00+01:00</deliverydateasked> 
     </article> 
</articles> 

essayant de convertir le xml à

<articles> 
     <article> 
      <articleid>48992</articleid> 
      <deliverydateasked>2009-01-29</deliverydateasked> 
     </article> 
     <article> 
      <articleid>48993</articleid> 
      <deliverydateasked>2009-01-30</deliverydateasked> 
     </article> 
</articles> 

actuellement j'utilise ce XSLT

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 
<xsl:template match="/"> 
    <articles> 
     <xsl:apply-templates select="article"> 
     </xsl:apply-templates> 
      </articles> 
</xsl:template> 

<xsl:template name="FormatDate"> 

    <xsl:param name="DateTime" /> 
    <xsl:variable name="date"> 
     <xsl:value-of select="substring-before($DateTime,'T')" /> 
    </xsl:variable> 

    <xsl:if test="string-length($date) != 10"> 
     <xsl:value-of select="$DateTime"/> 
    </xsl:if> 
    <xsl:if test="string-length($date) = 10"> 
     <xsl:value-of select="$date"/> 
    </xsl:if> 
</xsl:template> 

<xsl:template match="article"> 
     <xsl:call-template name="FormatDate"> 
      <xsl:with-param name="DateTime" select="deliverydateasked"/> 
     </xsl:call-template>  
</xsl:template>  

Est-ce que quelqu'un sait un bon xsl t transformation.

Merci à l'avance

Le résultat de sortie de mon code est

<articles /> 

Répondre

1

Merci à Stesoc et annakata I figured it out Ceci est le code que je suis maintenant en utilisant et il fonctionne parfaitement

<xsl:template match="*"> 
    <xsl:param name="parentElm"> 
     <xsl:value-of select="name(..)" /> 
    </xsl:param> 
    <xsl:choose> 
     <xsl:when test="local-name() = 'deliverydateasked'"> 
      <xsl:element name="deliverydateasked"> 
       <xsl:call-template name="FormatDate"> 
        <xsl:with-param name="DateTime" select="."/> 
       </xsl:call-template> 
      </xsl:element> 
     </xsl:when> 
     <xsl:otherwise> 
      <xsl:element name="{local-name()}"> 
       <xsl:copy-of select="@*" /> 
       <xsl:apply-templates select="@* | node()" /> 
      </xsl:element> 
     </xsl:otherwise> 
    </xsl:choose> 
</xsl:template> 

<xsl:template name="FormatDate"> 
    <xsl:param name="DateTime" /> 
    <xsl:variable name="date"> 
     <xsl:value-of select="substring-before($DateTime,'T')" /> 
    </xsl:variable> 

    <xsl:if test="string-length($date) != 10"> 
     <xsl:value-of select="$DateTime"/> 
    </xsl:if> 
    <xsl:if test="string-length($date) = 10"> 
     <xsl:value-of select="$date"/> 
    </xsl:if> 
</xsl:template>  

+0

Pourquoi faites-vous les choses compliquées "nom-local()"? – Tomalak

+0

ce que dit tomalak - levier xsl: copie – annakata

+0

Annakata J'ai essayé votre première suggestion avec le résultat: 2009-01 -292009-01-30 Ou est-ce que j'avais quelque chose de mal? mais local-name() est-il une fonction à éviter? la durée est maintenant 15-30 ms – freggel

7

Franchement, cela semble à peu près juste pour moi - parfois une sous-chaîne est simple assez bon.

Cependant, si vous êtes dans la terre .NET et vous vraiment besoin de fonctionnalités supplémentaires .NET a XSLT Extension Objects


modifier: oïque, vous avez un apply-templates de base problème conceptuel. Essayez ceci (notez la copie et le match de modèle racine):

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 

<xsl:template match="*"> 
    <xsl:copy><xsl:apply-templates /></xsl:copy> 
</xsl:template> 

<xsl:template match="deliverydateasked"> 
    <xsl:copy> 
     <xsl:call-template name="FormatDate"> 
      <xsl:with-param name="DateTime" select="."/> 
     </xsl:call-template>  
    </xsl:copy> 
</xsl:template> 

<xsl:template name="FormatDate"> 

     <xsl:param name="DateTime" /> 
     <xsl:variable name="date"> 
       <xsl:value-of select="substring-before($DateTime,'T')" /> 
     </xsl:variable> 

     <xsl:if test="string-length($date) != 10"> 
       <xsl:value-of select="$DateTime"/> 
     </xsl:if> 
     <xsl:if test="string-length($date) = 10"> 
       <xsl:value-of select="$date"/> 
     </xsl:if> 
</xsl:template> 

</xsl:stylesheet> 

modèles est un concept difficile à apprendre, vous pourriez être mieux commencer par le plus simple for-each, et/ou il semble que vous pourriez faire avec Tutoriels XSLT/livres.

+1

Sur "en utilisant le plus simple pour chacun": http://gregbeech.com/blogs/tech/archive/2006/08/17/using-xsl-for-each-is-almost-always-wrong.aspx .Je vote pour le faire correctement dès le début. :) – Tomalak

+0

De l'expérience personnelle d'enseigner XSLT aux débutants je suis fortement en désaccord avec cela - pour-chacun est un concept traduisible et facilement saisi, et si quelque chose est un tremplin pratique pour expliquer le concept de modèle "maintenant vous avez ça, voir ce cela peut faire! " – annakata

+1

Le lien que Tomalak a donné à l'article de Greg Beech a changé; c'est maintenant http://gregbeech.com/blog/using-xsl-for-each-is-almost-always-wrong – Val

6

Le formatage obtenir beaucoup plus facile à XPath 2.0, que Microsoft refuse actuellement de supporter depuis 8 ans. Étant donné que la question de la mise en forme est vraiment seulement persistant pour XSLT .Net Je préfère utiliser une fonction personnalisée, ce qui est plus propre & plus facile:

XSLT Avec la fonction de formatage:

xmlns="http://www.w3.org/1999/xhtml" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:msxsl="urn:schemas-microsoft-com:xslt" 
    xmlns:user="http://www.tempuri.org/User"> 

    <msxsl:script implements-prefix="user" language="C#"> 
     <![CDATA[ 
      public string FormatCurrency(string amount) 
      { 
      return decimal.Parse(amount).ToString("C0"); 
      } 

      public string FormatDate(string dateValue) 
      { 
      return DateTime.Parse(dateValue).ToString("MM/dd/yyyy hh:mm"); 
      } 
      ]]> 
     </msxsl:script> 

Utilisation:

<xsl:value-of select="user:FormatDate(@transactionDate)"/> 
<xsl:value-of select="user:FormatCurrency(@amount)"/> 

Lorsque vous exécutez votre XSLT en .Net assurez-vous de lui dire qu'il est digne de confiance (pour que le msxsl. bloc de script sera exécuté

XslCompiledTransform.Load(reader, XsltSettings.TrustedXslt, null);