Проверить IBAN с помощью XSLT 2.0? - PullRequest
3 голосов
/ 07 января 2011

можно ли написать функцию XSLT, которая может выполнять базовую проверку IBAN Mod-97?

Из Википедии:
1. Переместить четыре начальных символа в конец строки.
2. Замените каждую букву в строке двумя цифрами, расширив тем самым строку, где A = 10, B = 11, ..., Z = 35.
3. Интерпретируйте строку как десятичное целое число и вычислитеостаток от этого числа при делении на 97.

Если остаток равен 1, тест контрольных цифр пройден и IBAN может быть действительным.

Спасибо.

Ответы [ 2 ]

4 голосов
/ 07 января 2011

Это преобразование :

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

 <xsl:template match="text()">
  <xsl:sequence select="my:isIBAN(.)"/>
 </xsl:template>

 <xsl:function name="my:isIBAN" as="xs:boolean">
  <xsl:param name="pString" as="xs:string"/>

  <xsl:variable name="vDigits" select=
   "string-join(
                (for $vStarting4 in substring($pString, 1,4),
                     $vRest in substring($pString, 5),
                     $vNewString in concat($vRest,$vStarting4),
                     $vLen in string-length($vNewString),
                     $i in 1 to $vLen
                   return
                     my:code(substring($vNewString,$i,1))
                 ),
                 ''
                 )
   "/>

   <xsl:sequence select="xs:integer($vDigits) mod 97 eq 1"/>
 </xsl:function>

 <xsl:function name="my:code" as="xs:string">
  <xsl:param name="pChar" as="xs:string"/>

  <xsl:sequence select=
  "if(string-length($pChar) ne 1 or not(contains($vCaps, $pChar)))
     then $pChar
     else
      xs:string
         (string-to-codepoints($pChar) - string-to-codepoints('A') +10)
  "/>
 </xsl:function>
</xsl:stylesheet>

при применении к этому документу XML :

<t>GB82WEST12345698765432</t>

дает желаемый, правильный результат :

true

Примечание. : функция my:isIBAN() может быть реализована как одно выражение XPath 2.0. Я не предоставил это для удобства чтения.

2 голосов
/ 07 января 2011

Просто для удовольствия (я не видел, чтобы @Dimitre уже ответил на него)

<xsl:stylesheet version="2.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:xs="http://www.w3.org/2001/XMLSchema"
 xmlns:local="http://localhost/">
    <xsl:template match="IBAN[local:validate(.)]">
        <xsl:text>Validated IBAN</xsl:text>
    </xsl:template>
    <xsl:function name="local:validate">
        <xsl:param name="pIBAN" as="xs:string"/>
        <xsl:sequence select="xs:integer(
                                 codepoints-to-string(
                                    for $n in string-to-codepoints(
                                                 concat(
                                                    substring(
                                                       $pIBAN,
                                                       5
                                                    ),
                                                    substring(
                                                       $pIBAN,
                                                       1,
                                                       4
                                                    )
                                                 )
                                              )
                                    return if ($n > 64)
                                           then string-to-codepoints(
                                                   string(
                                                      $n - 55
                                                   )
                                                )
                                           else $n
                                 )
                              ) mod 97 eq 1"/>
    </xsl:function>
</xsl:stylesheet>

С этим входом:

<IBAN>GB82WEST12345698765432</IBAN>

Выход:

Validated IBAN

РЕДАКТИРОВАТЬ : лучше один вкладыш.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...