XSLT mod 检查大数

发布于 2024-12-26 06:17:36 字数 165 浏览 5 评论 0原文

我正在尝试在 XSLT 1.0 中对 17 位数字进行模数 11 检查。然而,它似乎总是给出错误的输出。

我能找到的关于此的唯一信息位于

我过去曾使用 Luhn 检查器的 XSLT 模板,我意识到这与模数检查的工作方式不同,但我想知道是否有人知道可以计算大数模数的 XSLT 模板?

I'm trying to do a modulus 11 check in XSLT 1.0 for a 17 digit number. 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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

陈独秀 2025-01-02 06:17:37

有一个纯 XSLT 1.0 解决方案,可以计算任意大小的整数 $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>

应用此转换时在以下 XML 文档上

<t>12345678901234567</t>

生成所需的正确结果 (12345678901234567 mod 11)

9

请注意

  1. 这个解决方案可以很容易地推广到计算任何整数$m$n mod $m——只需将$m作为第二个参数。

  2. 另一个概括是作为参数传递限制,超过该限制就无法使用 mod 运算符直接计算 $n mod $m 。当使用 XSLT 2.0 并将 $n 作为 xs:integerxs:decimal 时,这可能很有用。

  3. 另一种替代方法是使用 Saxon.NET XSLT 2.0 处理器或任何其他实现大整数算术的 XSLT 2.0 处理器。那么解决方案就是使用 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>

当此转换与 Saxon 9.1.07 应用于同一个 XML 文档(如上)时,会产生相同的正确结果:

9

There is a pure XSLT 1.0 solution which calculates $n mod 11 for integer $n of any size:

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

<t>12345678901234567</t>

the wanted correct result (12345678901234567 mod 11) is produced:

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.

  2. Another generalization is to pass as parameter the limit above which $n mod $m cannot be calculated directly using the mod operator. This can be useful when using XSLT 2.0 and having $n as either xs:integer or xs: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. Then the solution is just to use the mod operator:

....

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

9
回忆追雨的时光 2025-01-02 06:17:37

这是因为在 MSXML 中,数字类型相当于 .NET Double 数据类型,其精度为 15-16 位。
尝试这个示例:

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

输出:

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

我认为您可以使用 C# 或 JScript 扩展 XSLT,因为 MSXML 支持此功能。

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

That is because in MSXML number type is equivalent of .NET Double datatype, which has precision of 15-16 digits.
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.

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文