Question

Je suis en train de faire un module 11 contrôle dans XSLT 1.0 pour un nombre de 17 chiffres. Cependant, il semble toujours donner la sortie mal.

La seule information que je suis en mesure de trouver à ce sujet, était en cette après, cependant, aucune solution n'a été trouvée.

J'ai utilisé dans le passé un modèle XSLT pour un vérificateur Luhn, je me rends compte que cela fonctionne différemment à un contrôle de module, mais je me demandais si quelqu'un était au courant d'un modèle XSLT qui peut calculer moduluses d'un grand nombre?

Était-ce utile?

La solution

Il existe une solution XSLT pur 1,0 qui calcule $n mod 11 pour $n entier de toutes les tailles :

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:template match="/*">
     <xsl:call-template name="mod11"/>
 </xsl:template>

 <xsl:template name="mod11">
  <xsl:param name="pN" select="."/>

  <xsl:choose>
   <xsl:when test="not($pN > 9999999999999999)">
     <xsl:value-of select="$pN mod 11"/>
   </xsl:when>
   <xsl:otherwise>
      <xsl:variable name="vLen" select="string-length($pN)"/>

      <xsl:variable name="vLen1" select="$vLen -1"/>

      <xsl:variable name="vPart1" select=
          "substring($pN, 1, $vLen1)"/>

      <xsl:variable name="vPart2" select=
          "substring($pN, $vLen1 +1)"/>

      <xsl:variable name="vMod1">
       <xsl:call-template name="mod11">
         <xsl:with-param name="pN" select="$vPart1"/>
       </xsl:call-template>
      </xsl:variable>

      <xsl:variable name="vMod2" select="$vPart2 mod 11"/>

      <xsl:value-of select="(10*$vMod1 + $vMod2) mod 11"/>
   </xsl:otherwise>
  </xsl:choose>
 </xsl:template>
</xsl:stylesheet>

Lorsque cette transformation est appliquée sur le document XML suivant :

<t>12345678901234567</t>

voulait résultat correct (12345678901234567 mod 11) est produit :

9

Prenez note :

  1. Cette solution peut être facilement généralisée pour calculer $n mod $m pour tout entier $m -. Juste passer $m en tant que second paramètre

  2. Une autre généralisation consiste à faire passer en tant que paramètre de la limite au-delà duquel $n mod $m ne peut être calculée en utilisant directement l'opérateur de mod. Cela peut être utile lors de l'utilisation XSLT 2.0 et ayant $n que soit xs:integer ou xs:decimal.

  3. Une autre alternative consiste à utiliser le processeur XSLT Saxon.NET 2,0 ou tout autre processeur XSLT 2.0 qui met en oeuvre de l'arithmétique grand entier. Ensuite, la solution est juste pour utiliser l'opérateur mod:

....

<xsl:stylesheet version="2.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:template match="/*">
     <xsl:value-of select="xs:integer(.) mod 11"/>
 </xsl:template>
</xsl:stylesheet>

Lorsque cette transformation est appliquée Saxon 9.1.07 sur le même document XML (ci-dessus), est produit le même résultat correct:

9

Autres conseils

C'est parce que dans le type de numéro MSXML est équivalent de .NET Double type de données, qui a la précision des chiffres 15-16. Essayez cet exemple:

double d = 123456789012345678;
Console.WriteLine("{0:f}", d);
Console.WriteLine("{0:f}", d + 1);
Console.WriteLine("{0:f}", d % 3);

long l = 123456789012345678;
Console.WriteLine(l);
Console.WriteLine(l + 1);
Console.WriteLine(l % 3);

Sortie:

123456789012346000,00
123456789012346000,00
2,00
123456789012345678
123456789012345679
0

Je pense que vous pouvez étendre XSLT avec C # ou JScript, parce que MSXML supporte.

Référence: http://msdn.microsoft .com / fr-fr / bibliothèque / 533texsx (v = VS.100) .aspx , http://msdn.microsoft.com/en-us/magazine/cc302079.aspx

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top