简体   繁体   English

XSLT mod检查大数字

[英]XSLT mod check for large numbers

I'm trying to do a modulus 11 check in XSLT 1.0 for a 17 digit number. 我正在尝试在XSLT 1.0中对17位数进行模数11检查。 However, it always seems to give the wrong output. 但是,似乎总是给出错误的输出。

The only information I've been able to find about this, was in this post , however, no solution was found. 我能找到的唯一信息是在这篇文章中 ,然而,没有找到解决方案。

I have in the past used an XSLT template for a Luhn checker, I realise that this works differently to a modulus check but I was wondering if anyone was aware of an XSLT template which can calculate moduluses of large numbers? 我过去曾使用XSLT模板作为Luhn检查器,我意识到这与模数检查的工作方式不同,但我想知道是否有人知道可以计算大数模的XSLT模板?

There is a pure XSLT 1.0 solution which calculates $n mod 11 for integer $n of any size : 有一个纯XSLT 1.0解决方案,可以$n mod 11任何大小的整数$n计算$n mod 11

<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>

When this transformation is applied on the following XML document : 将此转换应用于以下XML文档时

<t>12345678901234567</t>

the wanted correct result ( 12345678901234567 mod 11 ) is produced : 产生了想要的正确结果( 12345678901234567 mod 11

9

Do note : 请注意

  1. This solution can easily be generalized to calculate $n mod $m for any integer $m -- just pass $m as a second parameter. 这个解决方案可以很容易地推广到任何整数$m $n mod $m $m - 只需将$m作为第二个参数传递。

  2. Another generalization is to pass as parameter the limit above which $n mod $m cannot be calculated directly using the mod operator. 另一个概括是作为参数传递上限,使用mod运算符无法直接计算$n mod $m This can be useful when using XSLT 2.0 and having $n as either xs:integer or xs:decimal . 当使用XSLT 2.0并将$n作为xs:integerxs:decimal时,这非常有用。

  3. Another alternative is to use the Saxon.NET XSLT 2.0 processor or any other XSLT 2.0 processor that implements Big Integer arithmetics. 另一种方法是使用Saxon.NET XSLT 2.0处理器或任何其他实现Big Integer算术的XSLT 2.0处理器。 Then the solution is just to use the mod operator: 然后解决方案就是使用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>

When this transformation is applied with Saxon 9.1.07 on the same XML document (above), the same correct result is produced: 当在同一XML文档(上面)中使用Saxon 9.1.07进行此转换时,会产生相同的正确结果:

9

That is because in MSXML number type is equivalent of .NET Double datatype, which has precision of 15-16 digits. 这是因为在MSXML中,数字类型相当于.NET Double数据类型,其精度为15-16位。 Try this sample: 试试这个样本:

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);

Output: 输出:

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

I think you can extend XSLT with C# or JScript, because MSXML supports this. 我认为您可以使用C#或JScript扩展XSLT,因为MSXML支持这一点。

Reference: http://msdn.microsoft.com/en-us/library/533texsx(v=VS.100).aspx , http://msdn.microsoft.com/en-us/magazine/cc302079.aspx 参考: http//msdn.microsoft.com/en-us/library/533texsxv = VS.100).aspxhttp//msdn.microsoft.com/en-us/magazine/cc302079.aspx

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM