Существует чистое решение XSLT 1.0, которое вычисляет $n mod 11
для целых чисел $n
любого размера :
<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
Примечание :
Это решение можно легко обобщить для вычисления $n mod $m
для любого целого числа $m
- просто передайте $m
в качестве второго параметра.
Другим обобщением является передача в качестве параметра предела, выше которого $n mod $m
нельзя вычислить напрямую с помощью оператора mod
. Это может быть полезно при использовании XSLT 2.0 и $n
в качестве xs:integer
или xs:decimal
.
Другой альтернативой является использование процессора Saxon.NET XSLT 2.0 или любого другого процессора XSLT 2.0, который реализует арифметику Big Integer. Тогда решение состоит в том, чтобы просто использовать оператор 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